agora inbox for [email protected]help / color / mirror / Atom feed
Re: [Proposal] Table-level Transparent Data Encryption (TDE) and Key Management Service (KMS) 553+ messages / 7 participants [nested] [flat]
* Re: [Proposal] Table-level Transparent Data Encryption (TDE) and Key Management Service (KMS) @ 2019-08-08 18:35 Bruce Momjian <[email protected]> 0 siblings, 1 reply; 553+ messages in thread From: Bruce Momjian @ 2019-08-08 18:35 UTC (permalink / raw) To: Stephen Frost <[email protected]>; +Cc: Joe Conway <[email protected]>; Peter Eisentraut <[email protected]>; Masahiko Sawada <[email protected]>; Tomas Vondra <[email protected]>; Robert Haas <[email protected]>; Antonin Houska <[email protected]>; Haribabu Kommi <[email protected]>; Moon, Insung <[email protected]>; Ibrar Ahmed <[email protected]>; pgsql-hackers On Tue, Jul 9, 2019 at 11:09:01AM -0400, Bruce Momjian wrote: > On Tue, Jul 9, 2019 at 10:59:12AM -0400, Stephen Frost wrote: > > * Bruce Momjian ([email protected]) wrote: > > I agree that all of that isn't necessary for an initial implementation, > > I was rather trying to lay out how we could improve on this in the > > future and why having the keying done at a tablespace level makes sense > > initially because we can then potentially move forward with further > > segregation to improve the situation. I do believe it's also useful in > > its own right, to be clear, just not as nice since a compromised backend > > could still get access to data in shared buffers that it really > > shouldn't be able to, even broadly, see. > > I think TDE is feature of questionable value at best and the idea that > we would fundmentally change the internals of Postgres to add more > features to it seems very unlikely. I realize we have to discuss it so > we don't block reasonable future feature development. I have a new crazy idea. I know we concluded that allowing multiple independent keys, e.g., per user, per table, didn't make sense since they have to be unlocked all the time, e.g., for crash recovery and vacuum freeze. However, that assumes that all heap/index pages are encrypted, and all of WAL. What if we encrypted only the user-data part of the page, i.e., tuple data. We left xmin/xmax unencrypted, and only stored the encrypted part of that data in WAL, and didn't encrypt any more of WAL. That might allow crash recovery and the freeze part of VACUUM FREEZE to work. (I don't think we could vacuum since we couldn't read the index pages to find the matching rows since the index values would be encrypted too. We might be able to not encrypt the tid in the index typle.) Is this something considering in version one of this feature? Probably not, but later? Never? Would the information leakage be too great, particularly from indexes? -- Bruce Momjian <[email protected]> http://momjian.us EnterpriseDB http://enterprisedb.com + As you are, so once was I. As I am, so you will be. + + Ancient Roman grave inscription + ^ permalink raw reply [nested|flat] 553+ messages in thread
* Re: [Proposal] Table-level Transparent Data Encryption (TDE) and Key Management Service (KMS) @ 2019-08-08 19:07 Stephen Frost <[email protected]> parent: Bruce Momjian <[email protected]> 0 siblings, 2 replies; 553+ messages in thread From: Stephen Frost @ 2019-08-08 19:07 UTC (permalink / raw) To: Bruce Momjian <[email protected]>; +Cc: Joe Conway <[email protected]>; Peter Eisentraut <[email protected]>; Masahiko Sawada <[email protected]>; Tomas Vondra <[email protected]>; Robert Haas <[email protected]>; Antonin Houska <[email protected]>; Haribabu Kommi <[email protected]>; Moon, Insung <[email protected]>; Ibrar Ahmed <[email protected]>; pgsql-hackers Greetings, * Bruce Momjian ([email protected]) wrote: > On Tue, Jul 9, 2019 at 11:09:01AM -0400, Bruce Momjian wrote: > > On Tue, Jul 9, 2019 at 10:59:12AM -0400, Stephen Frost wrote: > > > * Bruce Momjian ([email protected]) wrote: > > > I agree that all of that isn't necessary for an initial implementation, > > > I was rather trying to lay out how we could improve on this in the > > > future and why having the keying done at a tablespace level makes sense > > > initially because we can then potentially move forward with further > > > segregation to improve the situation. I do believe it's also useful in > > > its own right, to be clear, just not as nice since a compromised backend > > > could still get access to data in shared buffers that it really > > > shouldn't be able to, even broadly, see. > > > > I think TDE is feature of questionable value at best and the idea that > > we would fundmentally change the internals of Postgres to add more > > features to it seems very unlikely. I realize we have to discuss it so > > we don't block reasonable future feature development. > > I have a new crazy idea. I know we concluded that allowing multiple > independent keys, e.g., per user, per table, didn't make sense since > they have to be unlocked all the time, e.g., for crash recovery and > vacuum freeze. I'm a bit confused as I never agreed that made any sense and I continue to feel that it doesn't make sense to have one key for everything. Crash recovery doesn't happen "all the time" and neither does vacuum freeze, and autovacuum processes are independent of individual client backends- we don't need to (and shouldn't) have the keys in shared memory. > However, that assumes that all heap/index pages are encrypted, and all > of WAL. What if we encrypted only the user-data part of the page, i.e., > tuple data. We left xmin/xmax unencrypted, and only stored the > encrypted part of that data in WAL, and didn't encrypt any more of WAL. This is pretty much what Alvaro was suggesting a while ago, isn't it..? Have just the user data be encrypted in the table and in the WAL stream. > That might allow crash recovery and the freeze part of VACUUM FREEZE to > work. (I don't think we could vacuum since we couldn't read the index > pages to find the matching rows since the index values would be encrypted > too. We might be able to not encrypt the tid in the index typle.) Why do we need the indexed values to vacuum the index..? We don't today, as I recall. We would need the tids though, yes. > Is this something considering in version one of this feature? Probably > not, but later? Never? Would the information leakage be too great, > particularly from indexes? What would be leaking from the indexes..? That an encrypted blob in the index pointed to a given tid? Wouldn't someone be able to see that same information by looking directly at the relation too? Thanks, Stephen Attachments: [application/pgp-signature] signature.asc (819B, ../../[email protected]/2-signature.asc) download ^ permalink raw reply [nested|flat] 553+ messages in thread
* Re: [Proposal] Table-level Transparent Data Encryption (TDE) and Key Management Service (KMS) @ 2019-08-08 22:21 Tomas Vondra <[email protected]> parent: Stephen Frost <[email protected]> 1 sibling, 1 reply; 553+ messages in thread From: Tomas Vondra @ 2019-08-08 22:21 UTC (permalink / raw) To: Stephen Frost <[email protected]>; +Cc: Bruce Momjian <[email protected]>; Joe Conway <[email protected]>; Peter Eisentraut <[email protected]>; Masahiko Sawada <[email protected]>; Robert Haas <[email protected]>; Antonin Houska <[email protected]>; Haribabu Kommi <[email protected]>; Moon, Insung <[email protected]>; Ibrar Ahmed <[email protected]>; pgsql-hackers On Thu, Aug 08, 2019 at 03:07:59PM -0400, Stephen Frost wrote: >Greetings, > >* Bruce Momjian ([email protected]) wrote: >> On Tue, Jul 9, 2019 at 11:09:01AM -0400, Bruce Momjian wrote: >> > On Tue, Jul 9, 2019 at 10:59:12AM -0400, Stephen Frost wrote: >> > > * Bruce Momjian ([email protected]) wrote: >> > > I agree that all of that isn't necessary for an initial implementation, >> > > I was rather trying to lay out how we could improve on this in the >> > > future and why having the keying done at a tablespace level makes sense >> > > initially because we can then potentially move forward with further >> > > segregation to improve the situation. I do believe it's also useful in >> > > its own right, to be clear, just not as nice since a compromised backend >> > > could still get access to data in shared buffers that it really >> > > shouldn't be able to, even broadly, see. >> > >> > I think TDE is feature of questionable value at best and the idea that >> > we would fundmentally change the internals of Postgres to add more >> > features to it seems very unlikely. I realize we have to discuss it so >> > we don't block reasonable future feature development. >> >> I have a new crazy idea. I know we concluded that allowing multiple >> independent keys, e.g., per user, per table, didn't make sense since >> they have to be unlocked all the time, e.g., for crash recovery and >> vacuum freeze. > >I'm a bit confused as I never agreed that made any sense and I continue >to feel that it doesn't make sense to have one key for everything. > >Crash recovery doesn't happen "all the time" and neither does vacuum >freeze, and autovacuum processes are independent of individual client >backends- we don't need to (and shouldn't) have the keys in shared >memory. > Don't people do physical replication / HA pretty much all the time? >> However, that assumes that all heap/index pages are encrypted, and all >> of WAL. What if we encrypted only the user-data part of the page, i.e., >> tuple data. We left xmin/xmax unencrypted, and only stored the >> encrypted part of that data in WAL, and didn't encrypt any more of WAL. > >This is pretty much what Alvaro was suggesting a while ago, isn't it..? >Have just the user data be encrypted in the table and in the WAL stream. > It's also moving us much closer to pgcrypto-style encryption ... >> That might allow crash recovery and the freeze part of VACUUM FREEZE to >> work. (I don't think we could vacuum since we couldn't read the index >> pages to find the matching rows since the index values would be encrypted >> too. We might be able to not encrypt the tid in the index typle.) > >Why do we need the indexed values to vacuum the index..? We don't >today, as I recall. We would need the tids though, yes. > Well, we also do collect statistics on the data, for example. But even if we assume we wouldn't do that for encrypted indexes (which seems like a pretty bad idea to me), you'd probably end up leaking information about ordering of the values. Which is generally a pretty serious information leak, AFAICS. >> Is this something considering in version one of this feature? Probably >> not, but later? Never? Would the information leakage be too great, >> particularly from indexes? > >What would be leaking from the indexes..? That an encrypted blob in the >index pointed to a given tid? Wouldn't someone be able to see that same >information by looking directly at the relation too? > Ordering of values, for example. Depending on how exactly the data is encrypted we might also be leaking information about which values are equal, etc. It also seems quite a bit more expensive to use such index. regards -- Tomas Vondra http://www.2ndQuadrant.com PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services ^ permalink raw reply [nested|flat] 553+ messages in thread
* Re: [Proposal] Table-level Transparent Data Encryption (TDE) and Key Management Service (KMS) @ 2019-08-08 22:31 Stephen Frost <[email protected]> parent: Tomas Vondra <[email protected]> 0 siblings, 3 replies; 553+ messages in thread From: Stephen Frost @ 2019-08-08 22:31 UTC (permalink / raw) To: Tomas Vondra <[email protected]>; +Cc: Bruce Momjian <[email protected]>; Joe Conway <[email protected]>; Peter Eisentraut <[email protected]>; Masahiko Sawada <[email protected]>; Robert Haas <[email protected]>; Antonin Houska <[email protected]>; Haribabu Kommi <[email protected]>; Moon, Insung <[email protected]>; Ibrar Ahmed <[email protected]>; pgsql-hackers Greetings, * Tomas Vondra ([email protected]) wrote: > On Thu, Aug 08, 2019 at 03:07:59PM -0400, Stephen Frost wrote: > >* Bruce Momjian ([email protected]) wrote: > >>On Tue, Jul 9, 2019 at 11:09:01AM -0400, Bruce Momjian wrote: > >>> On Tue, Jul 9, 2019 at 10:59:12AM -0400, Stephen Frost wrote: > >>> > * Bruce Momjian ([email protected]) wrote: > >>> > I agree that all of that isn't necessary for an initial implementation, > >>> > I was rather trying to lay out how we could improve on this in the > >>> > future and why having the keying done at a tablespace level makes sense > >>> > initially because we can then potentially move forward with further > >>> > segregation to improve the situation. I do believe it's also useful in > >>> > its own right, to be clear, just not as nice since a compromised backend > >>> > could still get access to data in shared buffers that it really > >>> > shouldn't be able to, even broadly, see. > >>> > >>> I think TDE is feature of questionable value at best and the idea that > >>> we would fundmentally change the internals of Postgres to add more > >>> features to it seems very unlikely. I realize we have to discuss it so > >>> we don't block reasonable future feature development. > >> > >>I have a new crazy idea. I know we concluded that allowing multiple > >>independent keys, e.g., per user, per table, didn't make sense since > >>they have to be unlocked all the time, e.g., for crash recovery and > >>vacuum freeze. > > > >I'm a bit confused as I never agreed that made any sense and I continue > >to feel that it doesn't make sense to have one key for everything. > > > >Crash recovery doesn't happen "all the time" and neither does vacuum > >freeze, and autovacuum processes are independent of individual client > >backends- we don't need to (and shouldn't) have the keys in shared > >memory. > > Don't people do physical replication / HA pretty much all the time? Strictly speaking, that isn't actually crash recovery, it's physical replication / HA, and while those are certainly nice to have it's no guarantee that they're required or that you'd want to have the same keys for them- conceptually, at least, you could have WAL with one key that both sides know and then different keys for the actual data files, if we go with the approach where the WAL is encrypted with one key and then otherwise is plaintext. > >>However, that assumes that all heap/index pages are encrypted, and all > >>of WAL. What if we encrypted only the user-data part of the page, i.e., > >>tuple data. We left xmin/xmax unencrypted, and only stored the > >>encrypted part of that data in WAL, and didn't encrypt any more of WAL. > > > >This is pretty much what Alvaro was suggesting a while ago, isn't it..? > >Have just the user data be encrypted in the table and in the WAL stream. > > It's also moving us much closer to pgcrypto-style encryption ... Yes, it is, and there's good parts and bad parts to that, to be sure. > >>That might allow crash recovery and the freeze part of VACUUM FREEZE to > >>work. (I don't think we could vacuum since we couldn't read the index > >>pages to find the matching rows since the index values would be encrypted > >>too. We might be able to not encrypt the tid in the index typle.) > > > >Why do we need the indexed values to vacuum the index..? We don't > >today, as I recall. We would need the tids though, yes. > > Well, we also do collect statistics on the data, for example. But even > if we assume we wouldn't do that for encrypted indexes (which seems like > a pretty bad idea to me), you'd probably end up leaking information > about ordering of the values. Which is generally a pretty serious > information leak, AFAICS. I agree entirely that order information would be bad to leak- but this is all new ground here and we haven't actually sorted out what such a partially encrypted btree would look like. We don't actually have to have the down-links in the tree be unencrypted to allow vacuuming of leaf pages, after all. > >>Is this something considering in version one of this feature? Probably > >>not, but later? Never? Would the information leakage be too great, > >>particularly from indexes? > > > >What would be leaking from the indexes..? That an encrypted blob in the > >index pointed to a given tid? Wouldn't someone be able to see that same > >information by looking directly at the relation too? > > Ordering of values, for example. Depending on how exactly the data is > encrypted we might also be leaking information about which values are > equal, etc. It also seems quite a bit more expensive to use such index. Using an encrypted index isn't going to be free. It's not clear that this would be much more expensive than if the entire index is encrypted, or that people would actually be unhappy if there was such an additional expense if it meant that they could have vacuum run without the keys. Thanks, Stephen Attachments: [application/pgp-signature] signature.asc (819B, ../../[email protected]/2-signature.asc) download ^ permalink raw reply [nested|flat] 553+ messages in thread
* Re: [Proposal] Table-level Transparent Data Encryption (TDE) and Key Management Service (KMS) @ 2019-08-09 00:24 Bruce Momjian <[email protected]> parent: Stephen Frost <[email protected]> 1 sibling, 0 replies; 553+ messages in thread From: Bruce Momjian @ 2019-08-09 00:24 UTC (permalink / raw) To: Stephen Frost <[email protected]>; +Cc: Joe Conway <[email protected]>; Peter Eisentraut <[email protected]>; Masahiko Sawada <[email protected]>; Tomas Vondra <[email protected]>; Robert Haas <[email protected]>; Antonin Houska <[email protected]>; Haribabu Kommi <[email protected]>; Moon, Insung <[email protected]>; Ibrar Ahmed <[email protected]>; pgsql-hackers On Thu, Aug 8, 2019 at 03:07:59PM -0400, Stephen Frost wrote: > Greetings, > > * Bruce Momjian ([email protected]) wrote: > > On Tue, Jul 9, 2019 at 11:09:01AM -0400, Bruce Momjian wrote: > > > On Tue, Jul 9, 2019 at 10:59:12AM -0400, Stephen Frost wrote: > > > > * Bruce Momjian ([email protected]) wrote: > > > > I agree that all of that isn't necessary for an initial implementation, > > > > I was rather trying to lay out how we could improve on this in the > > > > future and why having the keying done at a tablespace level makes sense > > > > initially because we can then potentially move forward with further > > > > segregation to improve the situation. I do believe it's also useful in > > > > its own right, to be clear, just not as nice since a compromised backend > > > > could still get access to data in shared buffers that it really > > > > shouldn't be able to, even broadly, see. > > > > > > I think TDE is feature of questionable value at best and the idea that > > > we would fundmentally change the internals of Postgres to add more > > > features to it seems very unlikely. I realize we have to discuss it so > > > we don't block reasonable future feature development. > > > > I have a new crazy idea. I know we concluded that allowing multiple > > independent keys, e.g., per user, per table, didn't make sense since > > they have to be unlocked all the time, e.g., for crash recovery and > > vacuum freeze. > > I'm a bit confused as I never agreed that made any sense and I continue > to feel that it doesn't make sense to have one key for everything. I clearly explained why multiple keys, while desirable, have many negatives. If you want to address my replies, we can go over them again. What people want, and what we can reasonably accomplish, are two different things. > Crash recovery doesn't happen "all the time" and neither does vacuum > freeze, and autovacuum processes are independent of individual client > backends- we don't need to (and shouldn't) have the keys in shared > memory. Uh, I just don't know what that would look like, honestly. I am trying to get us toward something that is easily implemented and easy to control. > > However, that assumes that all heap/index pages are encrypted, and all > > of WAL. What if we encrypted only the user-data part of the page, i.e., > > tuple data. We left xmin/xmax unencrypted, and only stored the > > encrypted part of that data in WAL, and didn't encrypt any more of WAL. > > This is pretty much what Alvaro was suggesting a while ago, isn't it..? > Have just the user data be encrypted in the table and in the WAL stream. Well, I think he was saying that to reduce the overhead of encryption. I didn't see it as a way of allowing recovery and vacuum freeze. My exact reply was: > Well, you would need to decide what WAL information needs to be secured. > Is the fact an insert was performed on a table a security issue? > Depends on your risks. My point is that almost anything you do beyond > cluster-level encryption either adds complexity that is bug-prone or > fragile, or adds unacceptable overhead, or leaks security information. > > That might allow crash recovery and the freeze part of VACUUM FREEZE to > > work. (I don't think we could vacuum since we couldn't read the index > > pages to find the matching rows since the index values would be encrypted > > too. We might be able to not encrypt the tid in the index typle.) > > Why do we need the indexed values to vacuum the index..? We don't > today, as I recall. We would need the tids though, yes. Uh, well, if we are doing index cleaning by doing a sequential scan of the index, which I think we have done for many years, I think just looking at the tids should work. However, I don't know if we ever adjust index entries, like re-balance the trees. > > Is this something considering in version one of this feature? Probably > > not, but later? Never? Would the information leakage be too great, > > particularly from indexes? > > What would be leaking from the indexes..? That an encrypted blob in the > index pointed to a given tid? Wouldn't someone be able to see that same > information by looking directly at the relation too? Well, I assume we would encrypt the heap and its indexes. For example, if there is an employee table, and there is an index on the employee last name and employee salary, it would be trivial to get a list of employee salaries sorted by last name by just joining the tids, though you would not know the last names. That seems like an information leak to me. Plus, which tables were updated would be visible in WAL. And we would have issues with system tables, pg_statistics, and lots of other complexity. I can see value in eventually doing this, perhaps before we perform cluster-wide encryption, but doing it without cluster-wide encryption seems like it would leak too much information to be useful. -- Bruce Momjian <[email protected]> http://momjian.us EnterpriseDB http://enterprisedb.com + As you are, so once was I. As I am, so you will be. + + Ancient Roman grave inscription + ^ permalink raw reply [nested|flat] 553+ messages in thread
* Re: [Proposal] Table-level Transparent Data Encryption (TDE) and Key Management Service (KMS) @ 2019-08-09 01:25 Bruce Momjian <[email protected]> parent: Stephen Frost <[email protected]> 2 siblings, 1 reply; 553+ messages in thread From: Bruce Momjian @ 2019-08-09 01:25 UTC (permalink / raw) To: Stephen Frost <[email protected]>; +Cc: Tomas Vondra <[email protected]>; Joe Conway <[email protected]>; Peter Eisentraut <[email protected]>; Masahiko Sawada <[email protected]>; Robert Haas <[email protected]>; Antonin Houska <[email protected]>; Haribabu Kommi <[email protected]>; Moon, Insung <[email protected]>; Ibrar Ahmed <[email protected]>; pgsql-hackers On Thu, Aug 8, 2019 at 06:31:42PM -0400, Stephen Frost wrote: > > >Crash recovery doesn't happen "all the time" and neither does vacuum > > >freeze, and autovacuum processes are independent of individual client > > >backends- we don't need to (and shouldn't) have the keys in shared > > >memory. > > > > Don't people do physical replication / HA pretty much all the time? > > Strictly speaking, that isn't actually crash recovery, it's physical > replication / HA, and while those are certainly nice to have it's no > guarantee that they're required or that you'd want to have the same keys > for them- conceptually, at least, you could have WAL with one key that > both sides know and then different keys for the actual data files, if we > go with the approach where the WAL is encrypted with one key and then > otherwise is plaintext. Uh, yes, you could have two encryption keys in the data directory, one for heap/indexes, one for WAL, both unlocked with the same passphrase, but what would be the value in that? > > >>That might allow crash recovery and the freeze part of VACUUM FREEZE to > > >>work. (I don't think we could vacuum since we couldn't read the index > > >>pages to find the matching rows since the index values would be encrypted > > >>too. We might be able to not encrypt the tid in the index typle.) > > > > > >Why do we need the indexed values to vacuum the index..? We don't > > >today, as I recall. We would need the tids though, yes. > > > > Well, we also do collect statistics on the data, for example. But even > > if we assume we wouldn't do that for encrypted indexes (which seems like > > a pretty bad idea to me), you'd probably end up leaking information > > about ordering of the values. Which is generally a pretty serious > > information leak, AFAICS. > > I agree entirely that order information would be bad to leak- but this > is all new ground here and we haven't actually sorted out what such a > partially encrypted btree would look like. We don't actually have to > have the down-links in the tree be unencrypted to allow vacuuming of > leaf pages, after all. Agreed, but I think we kind of know that the value in cluster-wide encryption is different from multi-key encryption --- both have their value, but right now cluster-wide is the easiest and simplest, and probably meets more user needs than multi-key encryption. If others want to start scoping out what multi-key encryption would look like, we can discuss it. I personally would like to focus on cluster-wide encryption for PG 13. > > >>Is this something considering in version one of this feature? Probably > > >>not, but later? Never? Would the information leakage be too great, > > >>particularly from indexes? > > > > > >What would be leaking from the indexes..? That an encrypted blob in the > > >index pointed to a given tid? Wouldn't someone be able to see that same > > >information by looking directly at the relation too? > > > > Ordering of values, for example. Depending on how exactly the data is > > encrypted we might also be leaking information about which values are > > equal, etc. It also seems quite a bit more expensive to use such index. > > Using an encrypted index isn't going to be free. It's not clear that > this would be much more expensive than if the entire index is encrypted, > or that people would actually be unhappy if there was such an additional > expense if it meant that they could have vacuum run without the keys. Yes, I think it is information leakage that is always going to make multi-key unable to fulfill all the features of cluster-wide encryption. -- Bruce Momjian <[email protected]> http://momjian.us EnterpriseDB http://enterprisedb.com + As you are, so once was I. As I am, so you will be. + + Ancient Roman grave inscription + ^ permalink raw reply [nested|flat] 553+ messages in thread
* Re: [Proposal] Table-level Transparent Data Encryption (TDE) and Key Management Service (KMS) @ 2019-08-09 02:34 Sehrope Sarkuni <[email protected]> parent: Stephen Frost <[email protected]> 2 siblings, 1 reply; 553+ messages in thread From: Sehrope Sarkuni @ 2019-08-09 02:34 UTC (permalink / raw) To: Stephen Frost <[email protected]>; +Cc: Tomas Vondra <[email protected]>; Bruce Momjian <[email protected]>; Joe Conway <[email protected]>; Peter Eisentraut <[email protected]>; Masahiko Sawada <[email protected]>; Robert Haas <[email protected]>; Antonin Houska <[email protected]>; Haribabu Kommi <[email protected]>; Moon, Insung <[email protected]>; Ibrar Ahmed <[email protected]>; pgsql-hackers On Thu, Aug 8, 2019 at 6:31 PM Stephen Frost <[email protected]> wrote: > Strictly speaking, that isn't actually crash recovery, it's physical > replication / HA, and while those are certainly nice to have it's no > guarantee that they're required or that you'd want to have the same keys > for them- conceptually, at least, you could have WAL with one key that > both sides know and then different keys for the actual data files, if we > go with the approach where the WAL is encrypted with one key and then > otherwise is plaintext. > I like the idea of separating the WAL key from the rest of the data files. It'd all be unlocked by the MDEK and you'd still need derived keys per WAL-file, but disconnecting all that from the data files solves a lot of the problems with promoted replicas. This would complicate cloning a replica as using a different MDEK would involve decrypting / encrypting everything rather than just copying the files. Even if that's not baked in a first version, the separation allows for eventually supporting that. Regards, -- Sehrope Sarkuni Founder & CEO | JackDB, Inc. | https://www.jackdb.com/ ^ permalink raw reply [nested|flat] 553+ messages in thread
* Re: [Proposal] Table-level Transparent Data Encryption (TDE) and Key Management Service (KMS) @ 2019-08-09 14:51 Masahiko Sawada <[email protected]> parent: Bruce Momjian <[email protected]> 0 siblings, 2 replies; 553+ messages in thread From: Masahiko Sawada @ 2019-08-09 14:51 UTC (permalink / raw) To: Bruce Momjian <[email protected]>; +Cc: Stephen Frost <[email protected]>; Tomas Vondra <[email protected]>; Joe Conway <[email protected]>; Peter Eisentraut <[email protected]>; Robert Haas <[email protected]>; Antonin Houska <[email protected]>; Haribabu Kommi <[email protected]>; Moon, Insung <[email protected]>; Ibrar Ahmed <[email protected]>; pgsql-hackers On Fri, Aug 9, 2019 at 10:25 AM Bruce Momjian <[email protected]> wrote: > > On Thu, Aug 8, 2019 at 06:31:42PM -0400, Stephen Frost wrote: > > > >Crash recovery doesn't happen "all the time" and neither does vacuum > > > >freeze, and autovacuum processes are independent of individual client > > > >backends- we don't need to (and shouldn't) have the keys in shared > > > >memory. > > > > > > Don't people do physical replication / HA pretty much all the time? > > > > Strictly speaking, that isn't actually crash recovery, it's physical > > replication / HA, and while those are certainly nice to have it's no > > guarantee that they're required or that you'd want to have the same keys > > for them- conceptually, at least, you could have WAL with one key that > > both sides know and then different keys for the actual data files, if we > > go with the approach where the WAL is encrypted with one key and then > > otherwise is plaintext. > > Uh, yes, you could have two encryption keys in the data directory, one > for heap/indexes, one for WAL, both unlocked with the same passphrase, > but what would be the value in that? > > > > >>That might allow crash recovery and the freeze part of VACUUM FREEZE to > > > >>work. (I don't think we could vacuum since we couldn't read the index > > > >>pages to find the matching rows since the index values would be encrypted > > > >>too. We might be able to not encrypt the tid in the index typle.) > > > > > > > >Why do we need the indexed values to vacuum the index..? We don't > > > >today, as I recall. We would need the tids though, yes. > > > > > > Well, we also do collect statistics on the data, for example. But even > > > if we assume we wouldn't do that for encrypted indexes (which seems like > > > a pretty bad idea to me), you'd probably end up leaking information > > > about ordering of the values. Which is generally a pretty serious > > > information leak, AFAICS. > > > > I agree entirely that order information would be bad to leak- but this > > is all new ground here and we haven't actually sorted out what such a > > partially encrypted btree would look like. We don't actually have to > > have the down-links in the tree be unencrypted to allow vacuuming of > > leaf pages, after all. > > Agreed, but I think we kind of know that the value in cluster-wide > encryption is different from multi-key encryption --- both have their > value, but right now cluster-wide is the easiest and simplest, and > probably meets more user needs than multi-key encryption. If others > want to start scoping out what multi-key encryption would look like, we > can discuss it. I personally would like to focus on cluster-wide > encryption for PG 13. I agree that cluster-wide is more simpler but I'm not sure that it meets real needs from users. One example is re-encryption; when the key leakage happens, in cluster-wide encryption we end up with doing re-encrypt whole database regardless the amount of user sensitive data in database. I think it's a big constraint for users because it's common that the amount of data such as master table that needs to be encrypted doesn't account for a large potion of database. That's one reason why I think more fine granularity encryption such as table/tablespace is required. And in terms of feature development we would implement fine-granularity encryption in the future even if the first step is cluster-wide encryption? And both TDEs encrypt the same kind of database objects (i.e. only tables , indexes and WAL)? If so, how does users use them depending on cases? I imagined the case where we had the cluster-wide encryption as the first TDE feature. We will enable TDE at initdb time by specifying the command-line parameter for TDE. Then TDE is enabled in cluster wide and all tables/indexes and WAL are automatically encrypted. Then, if we want to implement the more fine granularity encryption how can we make users use it? WAL encryption and tables/index encryption are enabled at the same time but we want to enable encryption for particular tables/indexes after initdb. If the cluster-wide encryption is something like a short-cut of encrypting all tables/indexes, I personally think that implementing the more fine granularity one first and then using it to achieve the more coarse granularity would be more easier. Regards, -- Masahiko Sawada NIPPON TELEGRAPH AND TELEPHONE CORPORATION NTT Open Source Software Center ^ permalink raw reply [nested|flat] 553+ messages in thread
* Re: [Proposal] Table-level Transparent Data Encryption (TDE) and Key Management Service (KMS) @ 2019-08-09 15:01 Tomas Vondra <[email protected]> parent: Stephen Frost <[email protected]> 2 siblings, 1 reply; 553+ messages in thread From: Tomas Vondra @ 2019-08-09 15:01 UTC (permalink / raw) To: Stephen Frost <[email protected]>; +Cc: Bruce Momjian <[email protected]>; Joe Conway <[email protected]>; Peter Eisentraut <[email protected]>; Masahiko Sawada <[email protected]>; Robert Haas <[email protected]>; Antonin Houska <[email protected]>; Haribabu Kommi <[email protected]>; Moon, Insung <[email protected]>; Ibrar Ahmed <[email protected]>; pgsql-hackers On Thu, Aug 08, 2019 at 06:31:42PM -0400, Stephen Frost wrote: >Greetings, > >* Tomas Vondra ([email protected]) wrote: >> On Thu, Aug 08, 2019 at 03:07:59PM -0400, Stephen Frost wrote: >> >* Bruce Momjian ([email protected]) wrote: >> >>On Tue, Jul 9, 2019 at 11:09:01AM -0400, Bruce Momjian wrote: >> >>> On Tue, Jul 9, 2019 at 10:59:12AM -0400, Stephen Frost wrote: >> >>> > * Bruce Momjian ([email protected]) wrote: >> >>> > I agree that all of that isn't necessary for an initial implementation, >> >>> > I was rather trying to lay out how we could improve on this in the >> >>> > future and why having the keying done at a tablespace level makes sense >> >>> > initially because we can then potentially move forward with further >> >>> > segregation to improve the situation. I do believe it's also useful in >> >>> > its own right, to be clear, just not as nice since a compromised backend >> >>> > could still get access to data in shared buffers that it really >> >>> > shouldn't be able to, even broadly, see. >> >>> >> >>> I think TDE is feature of questionable value at best and the idea that >> >>> we would fundmentally change the internals of Postgres to add more >> >>> features to it seems very unlikely. I realize we have to discuss it so >> >>> we don't block reasonable future feature development. >> >> >> >>I have a new crazy idea. I know we concluded that allowing multiple >> >>independent keys, e.g., per user, per table, didn't make sense since >> >>they have to be unlocked all the time, e.g., for crash recovery and >> >>vacuum freeze. >> > >> >I'm a bit confused as I never agreed that made any sense and I continue >> >to feel that it doesn't make sense to have one key for everything. >> > >> >Crash recovery doesn't happen "all the time" and neither does vacuum >> >freeze, and autovacuum processes are independent of individual client >> >backends- we don't need to (and shouldn't) have the keys in shared >> >memory. >> >> Don't people do physical replication / HA pretty much all the time? > >Strictly speaking, that isn't actually crash recovery, it's physical >replication / HA, and while those are certainly nice to have it's no >guarantee that they're required or that you'd want to have the same keys >for them- conceptually, at least, you could have WAL with one key that >both sides know and then different keys for the actual data files, if we >go with the approach where the WAL is encrypted with one key and then >otherwise is plaintext. > Uh? IMHO not breaking physical replication / HA should be pretty much required for any new feature, unless it's somehow obviously clear that it's not needed for that particular feature. I very much doubt we can make that conclusion for encrypted instances (at least I don't see why it would be the case in general). One reason is that those features are also used for backups, which I hope we both agree is not an optional feature. Maybe it's possible to modify pg_basebackup to re-encrypt all the data, but to do that it clearly needs to know all encryption keys (although not necessarily on the same side). >> >>However, that assumes that all heap/index pages are encrypted, and all >> >>of WAL. What if we encrypted only the user-data part of the page, i.e., >> >>tuple data. We left xmin/xmax unencrypted, and only stored the >> >>encrypted part of that data in WAL, and didn't encrypt any more of WAL. >> > >> >This is pretty much what Alvaro was suggesting a while ago, isn't it..? >> >Have just the user data be encrypted in the table and in the WAL stream. >> >> It's also moving us much closer to pgcrypto-style encryption ... > >Yes, it is, and there's good parts and bad parts to that, to be sure. > >> >>That might allow crash recovery and the freeze part of VACUUM FREEZE to >> >>work. (I don't think we could vacuum since we couldn't read the index >> >>pages to find the matching rows since the index values would be encrypted >> >>too. We might be able to not encrypt the tid in the index typle.) >> > >> >Why do we need the indexed values to vacuum the index..? We don't >> >today, as I recall. We would need the tids though, yes. >> >> Well, we also do collect statistics on the data, for example. But even >> if we assume we wouldn't do that for encrypted indexes (which seems like >> a pretty bad idea to me), you'd probably end up leaking information >> about ordering of the values. Which is generally a pretty serious >> information leak, AFAICS. > >I agree entirely that order information would be bad to leak- but this >is all new ground here and we haven't actually sorted out what such a >partially encrypted btree would look like. We don't actually have to >have the down-links in the tree be unencrypted to allow vacuuming of >leaf pages, after all. > Well, I'm not all that familiar with the btree code, but I still think you can deduce an awful amount of information from having the leaf pages alone (not sure if we could deduce a total order, but presumably yes). >> >>Is this something considering in version one of this feature? Probably >> >>not, but later? Never? Would the information leakage be too great, >> >>particularly from indexes? >> > >> >What would be leaking from the indexes..? That an encrypted blob in the >> >index pointed to a given tid? Wouldn't someone be able to see that same >> >information by looking directly at the relation too? >> >> Ordering of values, for example. Depending on how exactly the data is >> encrypted we might also be leaking information about which values are >> equal, etc. It also seems quite a bit more expensive to use such index. > >Using an encrypted index isn't going to be free. It's not clear that >this would be much more expensive than if the entire index is encrypted, >or that people would actually be unhappy if there was such an additional >expense if it meant that they could have vacuum run without the keys. > With whole-page encryption, the page would be decrypted when loading it into shared buffers, and then accessed without encryption/decryption (at least that's how it was proposed initially). I assume we wouldn't do that when only encrypting the index keys (because that would mean anything that accesses the index through shared buffers has to do the decryption, including autovacuum et al). Which means you have to do decryption on each index access (which you previously did not). IMHO that's a pretty clear and significant additional overhead. I know there were proposals to keep it encrypted in shared buffers, but I'm not sure that's what we'll end up doing (I have not followed the recent discussion all that closely, though). regards -- Tomas Vondra http://www.2ndQuadrant.com PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services ^ permalink raw reply [nested|flat] 553+ messages in thread
* Re: [Proposal] Table-level Transparent Data Encryption (TDE) and Key Management Service (KMS) @ 2019-08-09 15:18 Tomas Vondra <[email protected]> parent: Masahiko Sawada <[email protected]> 1 sibling, 2 replies; 553+ messages in thread From: Tomas Vondra @ 2019-08-09 15:18 UTC (permalink / raw) To: Masahiko Sawada <[email protected]>; +Cc: Bruce Momjian <[email protected]>; Stephen Frost <[email protected]>; Joe Conway <[email protected]>; Peter Eisentraut <[email protected]>; Robert Haas <[email protected]>; Antonin Houska <[email protected]>; Haribabu Kommi <[email protected]>; Moon, Insung <[email protected]>; Ibrar Ahmed <[email protected]>; pgsql-hackers On Fri, Aug 09, 2019 at 11:51:23PM +0900, Masahiko Sawada wrote: >On Fri, Aug 9, 2019 at 10:25 AM Bruce Momjian <[email protected]> wrote: >> >> On Thu, Aug 8, 2019 at 06:31:42PM -0400, Stephen Frost wrote: >> > > >Crash recovery doesn't happen "all the time" and neither does vacuum >> > > >freeze, and autovacuum processes are independent of individual client >> > > >backends- we don't need to (and shouldn't) have the keys in shared >> > > >memory. >> > > >> > > Don't people do physical replication / HA pretty much all the time? >> > >> > Strictly speaking, that isn't actually crash recovery, it's physical >> > replication / HA, and while those are certainly nice to have it's no >> > guarantee that they're required or that you'd want to have the same keys >> > for them- conceptually, at least, you could have WAL with one key that >> > both sides know and then different keys for the actual data files, if we >> > go with the approach where the WAL is encrypted with one key and then >> > otherwise is plaintext. >> >> Uh, yes, you could have two encryption keys in the data directory, one >> for heap/indexes, one for WAL, both unlocked with the same passphrase, >> but what would be the value in that? >> >> > > >>That might allow crash recovery and the freeze part of VACUUM FREEZE to >> > > >>work. (I don't think we could vacuum since we couldn't read the index >> > > >>pages to find the matching rows since the index values would be encrypted >> > > >>too. We might be able to not encrypt the tid in the index typle.) >> > > > >> > > >Why do we need the indexed values to vacuum the index..? We don't >> > > >today, as I recall. We would need the tids though, yes. >> > > >> > > Well, we also do collect statistics on the data, for example. But even >> > > if we assume we wouldn't do that for encrypted indexes (which seems like >> > > a pretty bad idea to me), you'd probably end up leaking information >> > > about ordering of the values. Which is generally a pretty serious >> > > information leak, AFAICS. >> > >> > I agree entirely that order information would be bad to leak- but this >> > is all new ground here and we haven't actually sorted out what such a >> > partially encrypted btree would look like. We don't actually have to >> > have the down-links in the tree be unencrypted to allow vacuuming of >> > leaf pages, after all. >> >> Agreed, but I think we kind of know that the value in cluster-wide >> encryption is different from multi-key encryption --- both have their >> value, but right now cluster-wide is the easiest and simplest, and >> probably meets more user needs than multi-key encryption. If others >> want to start scoping out what multi-key encryption would look like, we >> can discuss it. I personally would like to focus on cluster-wide >> encryption for PG 13. > >I agree that cluster-wide is more simpler but I'm not sure that it >meets real needs from users. One example is re-encryption; when the >key leakage happens, in cluster-wide encryption we end up with doing >re-encrypt whole database regardless the amount of user sensitive data >in database. I think it's a big constraint for users because it's >common that the amount of data such as master table that needs to be >encrypted doesn't account for a large potion of database. That's one >reason why I think more fine granularity encryption such as >table/tablespace is required. > TBH I think it's mostly pointless to design for key leakage. My understanding it that all this work is motivated by the assumption that Bob can obtain access to the data directory (say, a backup of it). So if he also manages to get access to the encryption key, we probably have to assume he already has access to current snapshot of the data directory, which means any re-encryption is pretty futile. What we can (and should) optimize for is key rotation, but as that only changes the master key and not the actual encryption keys, the overhead is pretty low. We can of course support "forced" re-encryption, but I think it's acceptable if that's fairly expensive as long as it can be throttled and executed in the background (kinda similar to the patch to enable checksums in the background). >And in terms of feature development we would implement >fine-granularity encryption in the future even if the first step is >cluster-wide encryption? And both TDEs encrypt the same kind of >database objects (i.e. only tables , indexes and WAL)? If so, how >does users use them depending on cases? > >I imagined the case where we had the cluster-wide encryption as the >first TDE feature. We will enable TDE at initdb time by specifying the >command-line parameter for TDE. Then TDE is enabled in cluster wide >and all tables/indexes and WAL are automatically encrypted. Then, if >we want to implement the more fine granularity encryption how can we >make users use it? WAL encryption and tables/index encryption are >enabled at the same time but we want to enable encryption for >particular tables/indexes after initdb. If the cluster-wide encryption >is something like a short-cut of encrypting all tables/indexes, I >personally think that implementing the more fine granularity one first >and then using it to achieve the more coarse granularity would be more >easier. > Not sure, but I'd expect it to be the other way around, i.e. the more granular encryption being more complicated. One reason is that with cluster-wide you can just assume everything is encrypted and handle it the same way, while with fine-grained encryption you need to whether each individual object is encrypted, maybe handle it in different ways, etc. But that's just my guess, really. -- Tomas Vondra http://www.2ndQuadrant.com PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services ^ permalink raw reply [nested|flat] 553+ messages in thread
* Re: [Proposal] Table-level Transparent Data Encryption (TDE) and Key Management Service (KMS) @ 2019-08-10 02:17 Bruce Momjian <[email protected]> parent: Masahiko Sawada <[email protected]> 1 sibling, 0 replies; 553+ messages in thread From: Bruce Momjian @ 2019-08-10 02:17 UTC (permalink / raw) To: Masahiko Sawada <[email protected]>; +Cc: Stephen Frost <[email protected]>; Tomas Vondra <[email protected]>; Joe Conway <[email protected]>; Peter Eisentraut <[email protected]>; Robert Haas <[email protected]>; Antonin Houska <[email protected]>; Haribabu Kommi <[email protected]>; Moon, Insung <[email protected]>; Ibrar Ahmed <[email protected]>; pgsql-hackers On Fri, Aug 9, 2019 at 11:51:23PM +0900, Masahiko Sawada wrote: > I agree that cluster-wide is more simpler but I'm not sure that it > meets real needs from users. One example is re-encryption; when the > key leakage happens, in cluster-wide encryption we end up with doing > re-encrypt whole database regardless the amount of user sensitive data > in database. I think it's a big constraint for users because it's > common that the amount of data such as master table that needs to be > encrypted doesn't account for a large potion of database. That's one > reason why I think more fine granularity encryption such as > table/tablespace is required. > > And in terms of feature development we would implement > fine-granularity encryption in the future even if the first step is > cluster-wide encryption? And both TDEs encrypt the same kind of > database objects (i.e. only tables , indexes and WAL)? If so, how > does users use them depending on cases? > > I imagined the case where we had the cluster-wide encryption as the > first TDE feature. We will enable TDE at initdb time by specifying the > command-line parameter for TDE. Then TDE is enabled in cluster wide > and all tables/indexes and WAL are automatically encrypted. Then, if > we want to implement the more fine granularity encryption how can we > make users use it? WAL encryption and tables/index encryption are > enabled at the same time but we want to enable encryption for > particular tables/indexes after initdb. If the cluster-wide encryption > is something like a short-cut of encrypting all tables/indexes, I > personally think that implementing the more fine granularity one first > and then using it to achieve the more coarse granularity would be more > easier. I don't know how to move this thread forward, so I am going to try to explain how I view it. People want feature X and feature Y. Feature X seems straight-forward to implement, use, and seems secure. Feature Y is none of those, so far. When I explain that feature X is the direction we should go in for PG 13, people give more reasons they want feature Y, but don't give any details about how the problems of implemention, use, and security can be addressed. I just don't see that continuing to discuss feature Y with no details in how to implement it really helps, so I have no reply to these ideas. People can talk about whatever feature they want on these lists, but I have no way to help discussions that don't address facts. I will close with what I have already stated, that what people want, and what we can reasonably accomplish, are two different things. -- Bruce Momjian <[email protected]> http://momjian.us EnterpriseDB http://enterprisedb.com + As you are, so once was I. As I am, so you will be. + + Ancient Roman grave inscription + ^ permalink raw reply [nested|flat] 553+ messages in thread
* Re: [Proposal] Table-level Transparent Data Encryption (TDE) and Key Management Service (KMS) @ 2019-08-10 02:23 Bruce Momjian <[email protected]> parent: Sehrope Sarkuni <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Bruce Momjian @ 2019-08-10 02:23 UTC (permalink / raw) To: Sehrope Sarkuni <[email protected]>; +Cc: Stephen Frost <[email protected]>; Tomas Vondra <[email protected]>; Joe Conway <[email protected]>; Peter Eisentraut <[email protected]>; Masahiko Sawada <[email protected]>; Robert Haas <[email protected]>; Antonin Houska <[email protected]>; Haribabu Kommi <[email protected]>; Moon, Insung <[email protected]>; Ibrar Ahmed <[email protected]>; pgsql-hackers On Thu, Aug 8, 2019 at 10:34:26PM -0400, Sehrope Sarkuni wrote: > On Thu, Aug 8, 2019 at 6:31 PM Stephen Frost <[email protected]> wrote: > > Strictly speaking, that isn't actually crash recovery, it's physical > replication / HA, and while those are certainly nice to have it's no > guarantee that they're required or that you'd want to have the same keys > for them- conceptually, at least, you could have WAL with one key that > both sides know and then different keys for the actual data files, if we > go with the approach where the WAL is encrypted with one key and then > otherwise is plaintext. > > > I like the idea of separating the WAL key from the rest of the data files. > It'd all be unlocked by the MDEK and you'd still need derived keys per > WAL-file, but disconnecting all that from the data files solves a lot of the > problems with promoted replicas. > > This would complicate cloning a replica as using a different MDEK would involve > decrypting / encrypting everything rather than just copying the files. Even if > that's not baked in a first version, the separation allows for eventually > supporting that. OK, I can get behind that idea. One cool idea would be for the WAL on primary and standbys to use the same WAL key, but to use different heap/index keys. When the standby is promoted, there would be a way for the WAL to start using a new encryption key, and the heap/index would already be using its own encryption key. Setting up such a system seems complicated. The big problem is that the base backup would use the primary key, unless we allowed pg_basebackup to decrypt/encrypt with a new heap/index key. -- Bruce Momjian <[email protected]> http://momjian.us EnterpriseDB http://enterprisedb.com + As you are, so once was I. As I am, so you will be. + + Ancient Roman grave inscription + ^ permalink raw reply [nested|flat] 553+ messages in thread
* Re: [Proposal] Table-level Transparent Data Encryption (TDE) and Key Management Service (KMS) @ 2019-08-10 02:24 Bruce Momjian <[email protected]> parent: Tomas Vondra <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Bruce Momjian @ 2019-08-10 02:24 UTC (permalink / raw) To: Tomas Vondra <[email protected]>; +Cc: Stephen Frost <[email protected]>; Joe Conway <[email protected]>; Peter Eisentraut <[email protected]>; Masahiko Sawada <[email protected]>; Robert Haas <[email protected]>; Antonin Houska <[email protected]>; Haribabu Kommi <[email protected]>; Moon, Insung <[email protected]>; Ibrar Ahmed <[email protected]>; pgsql-hackers On Fri, Aug 9, 2019 at 05:01:47PM +0200, Tomas Vondra wrote: > I know there were proposals to keep it encrypted in shared buffers, but > I'm not sure that's what we'll end up doing (I have not followed the > recent discussion all that closely, though). There is no plan to encrypt shared buffers. -- Bruce Momjian <[email protected]> http://momjian.us EnterpriseDB http://enterprisedb.com + As you are, so once was I. As I am, so you will be. + + Ancient Roman grave inscription + ^ permalink raw reply [nested|flat] 553+ messages in thread
* Re: [Proposal] Table-level Transparent Data Encryption (TDE) and Key Management Service (KMS) @ 2019-08-13 06:30 Masahiko Sawada <[email protected]> parent: Tomas Vondra <[email protected]> 1 sibling, 0 replies; 553+ messages in thread From: Masahiko Sawada @ 2019-08-13 06:30 UTC (permalink / raw) To: Tomas Vondra <[email protected]>; +Cc: Bruce Momjian <[email protected]>; Stephen Frost <[email protected]>; Joe Conway <[email protected]>; Peter Eisentraut <[email protected]>; Robert Haas <[email protected]>; Antonin Houska <[email protected]>; Haribabu Kommi <[email protected]>; Moon, Insung <[email protected]>; Ibrar Ahmed <[email protected]>; pgsql-hackers On Sat, Aug 10, 2019 at 12:18 AM Tomas Vondra <[email protected]> wrote: > > On Fri, Aug 09, 2019 at 11:51:23PM +0900, Masahiko Sawada wrote: > >On Fri, Aug 9, 2019 at 10:25 AM Bruce Momjian <[email protected]> wrote: > >> > >> On Thu, Aug 8, 2019 at 06:31:42PM -0400, Stephen Frost wrote: > >> > > >Crash recovery doesn't happen "all the time" and neither does vacuum > >> > > >freeze, and autovacuum processes are independent of individual client > >> > > >backends- we don't need to (and shouldn't) have the keys in shared > >> > > >memory. > >> > > > >> > > Don't people do physical replication / HA pretty much all the time? > >> > > >> > Strictly speaking, that isn't actually crash recovery, it's physical > >> > replication / HA, and while those are certainly nice to have it's no > >> > guarantee that they're required or that you'd want to have the same keys > >> > for them- conceptually, at least, you could have WAL with one key that > >> > both sides know and then different keys for the actual data files, if we > >> > go with the approach where the WAL is encrypted with one key and then > >> > otherwise is plaintext. > >> > >> Uh, yes, you could have two encryption keys in the data directory, one > >> for heap/indexes, one for WAL, both unlocked with the same passphrase, > >> but what would be the value in that? > >> > >> > > >>That might allow crash recovery and the freeze part of VACUUM FREEZE to > >> > > >>work. (I don't think we could vacuum since we couldn't read the index > >> > > >>pages to find the matching rows since the index values would be encrypted > >> > > >>too. We might be able to not encrypt the tid in the index typle.) > >> > > > > >> > > >Why do we need the indexed values to vacuum the index..? We don't > >> > > >today, as I recall. We would need the tids though, yes. > >> > > > >> > > Well, we also do collect statistics on the data, for example. But even > >> > > if we assume we wouldn't do that for encrypted indexes (which seems like > >> > > a pretty bad idea to me), you'd probably end up leaking information > >> > > about ordering of the values. Which is generally a pretty serious > >> > > information leak, AFAICS. > >> > > >> > I agree entirely that order information would be bad to leak- but this > >> > is all new ground here and we haven't actually sorted out what such a > >> > partially encrypted btree would look like. We don't actually have to > >> > have the down-links in the tree be unencrypted to allow vacuuming of > >> > leaf pages, after all. > >> > >> Agreed, but I think we kind of know that the value in cluster-wide > >> encryption is different from multi-key encryption --- both have their > >> value, but right now cluster-wide is the easiest and simplest, and > >> probably meets more user needs than multi-key encryption. If others > >> want to start scoping out what multi-key encryption would look like, we > >> can discuss it. I personally would like to focus on cluster-wide > >> encryption for PG 13. > > > >I agree that cluster-wide is more simpler but I'm not sure that it > >meets real needs from users. One example is re-encryption; when the > >key leakage happens, in cluster-wide encryption we end up with doing > >re-encrypt whole database regardless the amount of user sensitive data > >in database. I think it's a big constraint for users because it's > >common that the amount of data such as master table that needs to be > >encrypted doesn't account for a large potion of database. That's one > >reason why I think more fine granularity encryption such as > >table/tablespace is required. > > > > TBH I think it's mostly pointless to design for key leakage. > > My understanding it that all this work is motivated by the assumption that > Bob can obtain access to the data directory (say, a backup of it). So if > he also manages to get access to the encryption key, we probably have to > assume he already has access to current snapshot of the data directory, > which means any re-encryption is pretty futile. > > What we can (and should) optimize for is key rotation, but as that only > changes the master key and not the actual encryption keys, the overhead is > pretty low. > > We can of course support "forced" re-encryption, but I think it's > acceptable if that's fairly expensive as long as it can be throttled and > executed in the background (kinda similar to the patch to enable checksums > in the background). I'm not sure that we can ignore the risk of MDEK leakage. Once MDEK is leaked for whatever reason all that is left for attacker is to steal data. User who realized that MDEK is leaked will have to re-encrypt data. Even if the data is already stolen user will want to re-encrypt data to protect further attacks. KEK rotation is futile in this case. > > >And in terms of feature development we would implement > >fine-granularity encryption in the future even if the first step is > >cluster-wide encryption? And both TDEs encrypt the same kind of > >database objects (i.e. only tables , indexes and WAL)? If so, how > >does users use them depending on cases? > > > >I imagined the case where we had the cluster-wide encryption as the > >first TDE feature. We will enable TDE at initdb time by specifying the > >command-line parameter for TDE. Then TDE is enabled in cluster wide > >and all tables/indexes and WAL are automatically encrypted. Then, if > >we want to implement the more fine granularity encryption how can we > >make users use it? WAL encryption and tables/index encryption are > >enabled at the same time but we want to enable encryption for > >particular tables/indexes after initdb. If the cluster-wide encryption > >is something like a short-cut of encrypting all tables/indexes, I > >personally think that implementing the more fine granularity one first > >and then using it to achieve the more coarse granularity would be more > >easier. > > > > Not sure, but I'd expect it to be the other way around, i.e. the more > granular encryption being more complicated. One reason is that with > cluster-wide you can just assume everything is encrypted and handle it the > same way, while with fine-grained encryption you need to whether each > individual object is encrypted, maybe handle it in different ways, etc. > > But that's just my guess, really. > I meant about the case where we want to implement both functionality(i.e., cluster wide for encryption everything and table/tablespace level for finer granularity encryption). If we want to have only either one the cluster-wide is easier as you mentioned. But if we want to have both of them I think that implementing finer granularity encryption first and using it to achieve coarse granularity encryption would be easier. Regards, -- Masahiko Sawada NIPPON TELEGRAPH AND TELEPHONE CORPORATION NTT Open Source Software Center ^ permalink raw reply [nested|flat] 553+ messages in thread
* RE: [Proposal] Table-level Transparent Data Encryption (TDE) and Key Management Service (KMS) @ 2019-08-13 07:56 Smith, Peter <[email protected]> parent: Tomas Vondra <[email protected]> 1 sibling, 0 replies; 553+ messages in thread From: Smith, Peter @ 2019-08-13 07:56 UTC (permalink / raw) To: Tomas Vondra <[email protected]>; Masahiko Sawada <[email protected]>; +Cc: Bruce Momjian <[email protected]>; Stephen Frost <[email protected]>; Joe Conway <[email protected]>; Peter Eisentraut <[email protected]>; Robert Haas <[email protected]>; Antonin Houska <[email protected]>; Haribabu Kommi <[email protected]>; Moon, Insung <[email protected]>; Ibrar Ahmed <[email protected]>; pgsql-hackers On Sat, Aug 10, 2019 at 1:19 AM Tomas Vondra <[email protected]> wrote: > We can of course support "forced" re-encryption, but I think it's acceptable if that's fairly expensive as long as it can be throttled and executed in the background (kinda similar to the patch to enable checksums in the background). As an alternative way to provide for a "forced" re-encryption couldn't you just run pg_dumpall + psql? Regards, -- Peter Smith Fujitsu Australia ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 553+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 553+ messages in thread
end of thread, other threads:[~2025-09-04 14:34 UTC | newest] Thread overview: 553+ messages (download: mbox mbox.gz follow: Atom feed) -- links below jump to the message on this page -- 2019-08-08 18:35 Re: [Proposal] Table-level Transparent Data Encryption (TDE) and Key Management Service (KMS) Bruce Momjian <[email protected]> 2019-08-08 19:07 ` Stephen Frost <[email protected]> 2019-08-08 22:21 ` Tomas Vondra <[email protected]> 2019-08-08 22:31 ` Stephen Frost <[email protected]> 2019-08-09 01:25 ` Bruce Momjian <[email protected]> 2019-08-09 14:51 ` Masahiko Sawada <[email protected]> 2019-08-09 15:18 ` Tomas Vondra <[email protected]> 2019-08-13 06:30 ` Masahiko Sawada <[email protected]> 2019-08-13 07:56 ` Smith, Peter <[email protected]> 2019-08-10 02:17 ` Bruce Momjian <[email protected]> 2019-08-09 02:34 ` Sehrope Sarkuni <[email protected]> 2019-08-10 02:23 ` Bruce Momjian <[email protected]> 2019-08-09 15:01 ` Tomas Vondra <[email protected]> 2019-08-10 02:24 ` Bruce Momjian <[email protected]> 2019-08-09 00:24 ` Bruce Momjian <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[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