Обсуждение: Re: proposal: schema variables
Hi folks, Thanks for continuing this work. As a side note, I would like to mention how strange the situation in this CF item is. If I understand correctly, there are two hackers threads discussing the same patch, with recent patches posted in both of them. This is obviously confusing, e.g. the main concern from another thread, about names clashing, wasn't even mentioned in this one. Is it possible to reconcile development in one thread?
ne 10. 11. 2024 v 16:24 odesílatel Dmitry Dolgov <9erthalion6@gmail.com> napsal:
Hi folks,
Thanks for continuing this work. As a side note, I would like to mention
how strange the situation in this CF item is. If I understand correctly,
there are two hackers threads discussing the same patch, with recent
patches posted in both of them. This is obviously confusing, e.g. the
main concern from another thread, about names clashing, wasn't even
mentioned in this one. Is it possible to reconcile development in one
thread?
This is probably my error. I don't try to organize threads, just I'll try to reply in the thread where I got a question.
Regards
Pavel
> On Sun, Nov 10, 2024 at 05:19:09PM GMT, Pavel Stehule wrote: > ne 10. 11. 2024 v 16:24 odesílatel Dmitry Dolgov <9erthalion6@gmail.com> > napsal: > > > Hi folks, > > > > Thanks for continuing this work. As a side note, I would like to mention > > how strange the situation in this CF item is. If I understand correctly, > > there are two hackers threads discussing the same patch, with recent > > patches posted in both of them. This is obviously confusing, e.g. the > > main concern from another thread, about names clashing, wasn't even > > mentioned in this one. Is it possible to reconcile development in one > > thread? > > > > This is probably my error. I don't try to organize threads, just I'll try > to reply in the thread where I got a question. It's fine. I just would appreciate some clarity about which patch to look at. To confirm, the series in this thread contains everything from the other one, plus some improvements, right?
ne 10. 11. 2024 v 17:19 odesílatel Pavel Stehule <pavel.stehule@gmail.com> napsal:
ne 10. 11. 2024 v 16:24 odesílatel Dmitry Dolgov <9erthalion6@gmail.com> napsal:Hi folks,
Thanks for continuing this work. As a side note, I would like to mention
how strange the situation in this CF item is. If I understand correctly,
there are two hackers threads discussing the same patch, with recent
patches posted in both of them. This is obviously confusing, e.g. the
main concern from another thread, about names clashing, wasn't even
mentioned in this one. Is it possible to reconcile development in one
thread?This is probably my error. I don't try to organize threads, just I'll try to reply in the thread where I got a question.
I thought a lot of time about better solutions for identifier collisions and I really don't think so there is some consistent user friendly syntax. Personally I think there is an easy already implemented solution - convention - just use a dedicated schema for variables and this schema should not be in the search path. Or use secondary convention - like using prefix "__" for session variables. Common convention is using "_" for PLpgSQL variables. I searched how this issue is solved in other databases, or in standard, and I found nothing special. The Oracle and SQL/PSM has a concept of visibility - the variables are not visible outside packages or modules, but Postgres has nothing similar. It can be emulated by a dedicated schema without inserting a search path, but it is less strong.
I think we can introduce an alternative syntax, that will not be user friendly or readable friendly, but it can be without collisions - or can decrease possible risks.
It is nothing new - SQL does it with old, "new" syntax of inner joins, or in Postgres we can
where salary < 40000
or
where pg_catalog.int4lt(salary, 40000);
or some like we use for operators
OPERATOR(
schema
.
operatorname
)
So introducing VARIABLE(schema.variablename) syntax as an alternative syntax for accessing variables I really like. I strongly prefer to use this as only alternative (secondary) syntax, because I don't think it is friendly syntax or writing friendly, but it is safe, and I can imagine tools that can replace generic syntax to this special, or that detects generic syntax and shows some warning. Then users can choose what they prefer. Two syntaxes - generic and special can be good enough for all - and this can be perfectly consistent with current Postgres.
Regards
Pavel
RegardsPavel
ne 10. 11. 2024 v 18:41 odesílatel Dmitry Dolgov <9erthalion6@gmail.com> napsal:
> On Sun, Nov 10, 2024 at 05:19:09PM GMT, Pavel Stehule wrote:
> ne 10. 11. 2024 v 16:24 odesílatel Dmitry Dolgov <9erthalion6@gmail.com>
> napsal:
>
> > Hi folks,
> >
> > Thanks for continuing this work. As a side note, I would like to mention
> > how strange the situation in this CF item is. If I understand correctly,
> > there are two hackers threads discussing the same patch, with recent
> > patches posted in both of them. This is obviously confusing, e.g. the
> > main concern from another thread, about names clashing, wasn't even
> > mentioned in this one. Is it possible to reconcile development in one
> > thread?
> >
>
> This is probably my error. I don't try to organize threads, just I'll try
> to reply in the thread where I got a question.
It's fine. I just would appreciate some clarity about which patch to
look at. To confirm, the series in this thread contains everything from
the other one, plus some improvements, right?
I don't remember any change that can be visible for users in this thread. Laurens does very precious code review (thank you again) - there are bigger changes in comments, and less changes in code - some parts of code are moved between patches, some lines were redundant and removed, some lines were artefacts of some git work and were cleaned. Some redundant tests were removed. There is no new code.
Regards
Pavel
ne 10. 11. 2024 v 18:51 odesílatel Pavel Stehule <pavel.stehule@gmail.com> napsal:
ne 10. 11. 2024 v 17:19 odesílatel Pavel Stehule <pavel.stehule@gmail.com> napsal:ne 10. 11. 2024 v 16:24 odesílatel Dmitry Dolgov <9erthalion6@gmail.com> napsal:Hi folks,
Thanks for continuing this work. As a side note, I would like to mention
how strange the situation in this CF item is. If I understand correctly,
there are two hackers threads discussing the same patch, with recent
patches posted in both of them. This is obviously confusing, e.g. the
main concern from another thread, about names clashing, wasn't even
mentioned in this one. Is it possible to reconcile development in one
thread?This is probably my error. I don't try to organize threads, just I'll try to reply in the thread where I got a question.I thought a lot of time about better solutions for identifier collisions and I really don't think so there is some consistent user friendly syntax. Personally I think there is an easy already implemented solution - convention - just use a dedicated schema for variables and this schema should not be in the search path. Or use secondary convention - like using prefix "__" for session variables. Common convention is using "_" for PLpgSQL variables. I searched how this issue is solved in other databases, or in standard, and I found nothing special. The Oracle and SQL/PSM has a concept of visibility - the variables are not visible outside packages or modules, but Postgres has nothing similar. It can be emulated by a dedicated schema without inserting a search path, but it is less strong.
There can be more collisions in Oracle, because the functions without arguments don't need parentheses. Postgres is safer, because this syntax is not allowed.
I think we can introduce an alternative syntax, that will not be user friendly or readable friendly, but it can be without collisions - or can decrease possible risks.It is nothing new - SQL does it with old, "new" syntax of inner joins, or in Postgres we canwhere salary < 40000or
where pg_catalog.int4lt(salary, 40000);or some like we use for operatorsOPERATOR(
schema
.
operatorname
)
So introducing VARIABLE(schema.variablename) syntax as an alternative syntax for accessing variables I really like. I strongly prefer to use this as only alternative (secondary) syntax, because I don't think it is friendly syntax or writing friendly, but it is safe, and I can imagine tools that can replace generic syntax to this special, or that detects generic syntax and shows some warning. Then users can choose what they prefer. Two syntaxes - generic and special can be good enough for all - and this can be perfectly consistent with current Postgres.RegardsPavelRegardsPavel
> On Sun, Nov 10, 2024 at 06:51:40PM GMT, Pavel Stehule wrote: > ne 10. 11. 2024 v 17:19 odesílatel Pavel Stehule <pavel.stehule@gmail.com> > napsal: > I thought a lot of time about better solutions for identifier collisions > and I really don't think so there is some consistent user friendly syntax. > Personally I think there is an easy already implemented solution - > convention - just use a dedicated schema for variables and this schema > should not be in the search path. Or use secondary convention - like using > prefix "__" for session variables. Common convention is using "_" for > PLpgSQL variables. I searched how this issue is solved in other databases, > or in standard, and I found nothing special. The Oracle and SQL/PSM has a > concept of visibility - the variables are not visible outside packages or > modules, but Postgres has nothing similar. It can be emulated by a > dedicated schema without inserting a search path, but it is less strong. > > I think we can introduce an alternative syntax, that will not be user > friendly or readable friendly, but it can be without collisions - or can > decrease possible risks. > > It is nothing new - SQL does it with old, "new" syntax of inner joins, or > in Postgres we can > > where salary < 40000 > > or > > where pg_catalog.int4lt(salary, 40000); > > > or some like we use for operators OPERATOR(*schema*.*operatorname*) > > So introducing VARIABLE(schema.variablename) syntax as an alternative > syntax for accessing variables I really like. I strongly prefer to use this > as only alternative (secondary) syntax, because I don't think it is > friendly syntax or writing friendly, but it is safe, and I can imagine > tools that can replace generic syntax to this special, or that detects > generic syntax and shows some warning. Then users can choose what they > prefer. Two syntaxes - generic and special can be good enough for all - and > this can be perfectly consistent with current Postgres. As far as I recall, last time this topic was discussed in hackers, two options were proposed: the one with VARIABLE(name), what you mention here; and another one with adding variables to the FROM clause. The VARIABLE(...) syntax didn't get much negative feedback, so I guess why not -- if you find it fitting, it would be interesting to see the implementation. I'm afraid it should not be just an alternative syntax, but the only one allowed, because otherwise I don't see how scenarious like "drop a column with the same name" could be avoided. As in the previous thread: -- we've got a variable b at the same time SELECT a, b FROM table1; Then dropping the column b, but everything still works beause the variable b got silently picked up. But if it would be required to say VARIABLE(b), then all fine. And to make sure we're on the same page, could you post couple of examples from curretly existing tests in the patch, how are they going to look like with this proposal? About adding variables to the FROM clause. Looks like this option was quite popular, and you've mentioned some technical challenges implementing that. If you'd like to go with another approach, it would be great to elaborate on that -- maybe even with a PoC, to make a convincing point here.
st 13. 11. 2024 v 17:35 odesílatel Dmitry Dolgov <9erthalion6@gmail.com> napsal:
> On Sun, Nov 10, 2024 at 06:51:40PM GMT, Pavel Stehule wrote:
> ne 10. 11. 2024 v 17:19 odesílatel Pavel Stehule <pavel.stehule@gmail.com>
> napsal:
> I thought a lot of time about better solutions for identifier collisions
> and I really don't think so there is some consistent user friendly syntax.
> Personally I think there is an easy already implemented solution -
> convention - just use a dedicated schema for variables and this schema
> should not be in the search path. Or use secondary convention - like using
> prefix "__" for session variables. Common convention is using "_" for
> PLpgSQL variables. I searched how this issue is solved in other databases,
> or in standard, and I found nothing special. The Oracle and SQL/PSM has a
> concept of visibility - the variables are not visible outside packages or
> modules, but Postgres has nothing similar. It can be emulated by a
> dedicated schema without inserting a search path, but it is less strong.
>
> I think we can introduce an alternative syntax, that will not be user
> friendly or readable friendly, but it can be without collisions - or can
> decrease possible risks.
>
> It is nothing new - SQL does it with old, "new" syntax of inner joins, or
> in Postgres we can
>
> where salary < 40000
>
> or
>
> where pg_catalog.int4lt(salary, 40000);
>
>
> or some like we use for operators OPERATOR(*schema*.*operatorname*)
>
> So introducing VARIABLE(schema.variablename) syntax as an alternative
> syntax for accessing variables I really like. I strongly prefer to use this
> as only alternative (secondary) syntax, because I don't think it is
> friendly syntax or writing friendly, but it is safe, and I can imagine
> tools that can replace generic syntax to this special, or that detects
> generic syntax and shows some warning. Then users can choose what they
> prefer. Two syntaxes - generic and special can be good enough for all - and
> this can be perfectly consistent with current Postgres.
As far as I recall, last time this topic was discussed in hackers, two
options were proposed: the one with VARIABLE(name), what you mention
here; and another one with adding variables to the FROM clause. The
VARIABLE(...) syntax didn't get much negative feedback, so I guess why
not -- if you find it fitting, it would be interesting to see the
implementation.
I'm afraid it should not be just an alternative syntax, but the only one
allowed, because otherwise I don't see how scenarious like "drop a
column with the same name" could be avoided. As in the previous thread:
-- we've got a variable b at the same time
SELECT a, b FROM table1;
I am sorry, but I am in very strong opposition against this idea. Nobody did reply to my questions, that can change my opinion.
1. This introduces possible inconsistency between LET syntax and SELECT syntax.
What will be the syntax of LET?
LET var = var FROM var
PLpgSQL does something, and it is really strange, and source of some unwanted bugs. See https://commitfest.postgresql.org/50/5044/
With current design I can support
LET var = expr with wars
or
LET var = (QUERY with vars)
It is perfectly consistent. The expressions will be expressions.
2. I don't know of any product in the world that introduced the same requirement. So this syntax will be proprietary (SQL/PSM it really doesn't require) and shock for any users that know other databases. Proprietary syntax in this area far from syntaxes of other products is hell. Try to explain to users the working with OUT variables of Postgres's procedures and functions. And there is some deeper logic.
3. There is a simple solution - convention. Use your own schema like vars, and use session variables in this schema, When this schema will not be on the search path, then there is not a collision.
Variables living in schema. Nobody without CREATE right can create it. So it is safe. Or use prefix in __ for variables in the search path.
4. this requirement introduces syntax inconsistency between plpgsql variables and session variables - which breaks one goal of the patch - introducing some global variables for plpgsql (and for all PL).
5. Using more variables and FROM clauses decrease readability of FROM clause
SELECT v1, v2, a, b, c FROM t1, v1, v2, t2, ...
6. Usually composite variables don't want to unpack. When you should use FROM clause, then composite variables will be unpacked. Then all fields can be possibly in collision with all other column name
Example
CREATE TYPE t1 AS (id int, name varchar)
CREATE TABLE tab(id int, name varchar)
CREATE VARIABLE var1 AS t1;
SELECT id, name, foo(var1) FROM tab, var1;
Now I have a collision in columns id, name, and everywhere I need to use aliases. Without necessity to use var in FROM clause, I can just write
SELECT id, name, foo(var) FROM tab
and there is not any risk of collision
Then dropping the column b, but everything still works beause the
variable b got silently picked up. But if it would be required to say
VARIABLE(b), then all fine.
but same risk you have any time in plpgsql - all time. I don't remember any bug report related to this issue.
And to make sure we're on the same page, could you post couple of
examples from curretly existing tests in the patch, how are they going
to look like with this proposal?
About adding variables to the FROM clause. Looks like this option was
quite popular, and you've mentioned some technical challenges
implementing that. If you'd like to go with another approach, it would
be great to elaborate on that -- maybe even with a PoC, to make a
convincing point here.
There is not any problem with implementation. I see the main problem with usability, and I really don't want to implement some like LET var = var FROM var; I am sorry
It fixes one issue, but it increases possible collisions - so the variables will be unusable.
Regards
Pavel
st 13. 11. 2024 v 17:35 odesílatel Dmitry Dolgov <9erthalion6@gmail.com> napsal:
> On Sun, Nov 10, 2024 at 06:51:40PM GMT, Pavel Stehule wrote:
> ne 10. 11. 2024 v 17:19 odesílatel Pavel Stehule <pavel.stehule@gmail.com>
> napsal:
> I thought a lot of time about better solutions for identifier collisions
> and I really don't think so there is some consistent user friendly syntax.
> Personally I think there is an easy already implemented solution -
> convention - just use a dedicated schema for variables and this schema
> should not be in the search path. Or use secondary convention - like using
> prefix "__" for session variables. Common convention is using "_" for
> PLpgSQL variables. I searched how this issue is solved in other databases,
> or in standard, and I found nothing special. The Oracle and SQL/PSM has a
> concept of visibility - the variables are not visible outside packages or
> modules, but Postgres has nothing similar. It can be emulated by a
> dedicated schema without inserting a search path, but it is less strong.
>
> I think we can introduce an alternative syntax, that will not be user
> friendly or readable friendly, but it can be without collisions - or can
> decrease possible risks.
>
> It is nothing new - SQL does it with old, "new" syntax of inner joins, or
> in Postgres we can
>
> where salary < 40000
>
> or
>
> where pg_catalog.int4lt(salary, 40000);
>
>
> or some like we use for operators OPERATOR(*schema*.*operatorname*)
>
> So introducing VARIABLE(schema.variablename) syntax as an alternative
> syntax for accessing variables I really like. I strongly prefer to use this
> as only alternative (secondary) syntax, because I don't think it is
> friendly syntax or writing friendly, but it is safe, and I can imagine
> tools that can replace generic syntax to this special, or that detects
> generic syntax and shows some warning. Then users can choose what they
> prefer. Two syntaxes - generic and special can be good enough for all - and
> this can be perfectly consistent with current Postgres.
As far as I recall, last time this topic was discussed in hackers, two
options were proposed: the one with VARIABLE(name), what you mention
here; and another one with adding variables to the FROM clause. The
VARIABLE(...) syntax didn't get much negative feedback, so I guess why
not -- if you find it fitting, it would be interesting to see the
implementation.
I'm afraid it should not be just an alternative syntax, but the only one
allowed, because otherwise I don't see how scenarious like "drop a
column with the same name" could be avoided. As in the previous thread:
-- we've got a variable b at the same time
SELECT a, b FROM table1;
Then dropping the column b, but everything still works beause the
variable b got silently picked up. But if it would be required to say
VARIABLE(b), then all fine.
In this scenario you will get a warning related to variable shadowing (before you drop a column).
I think this issue can be partially similar to creating two equally named tables in different schemas (both schemas are in search path). When you drop one table, the query will work, but the result is different. It is the same issue. The SQL has no concept of shadowing and on the base line it is not necessary. But when you integrate SQL with some procedural code then you should solve this issue (or accept). This issue is real, and it is in every procedural enhancement of SQL that I know with the same syntax. On the other hand I doubt this is a real issue. The changes of system catalogue are tested before production - so probably you will read a warning about a shadowed variable, and probably you will get different results, because variable b has the same value for all rows, and probably will have different value than column b. I can imagine the necessity of disabling this warning on production systems. Shadowing by self is not an issue, probably, but it is a signal of code quality problems.
But this scenario is real, and then it is a question if the warning about shadowed variables should be only optional and if it can be disabled. Maybe not. Generally the shadowing is a strange concept - it is safeguard against serious issues, but it should not be used generally and everywhere the developer should rename the conflict identifiers.
Regards
Pavel
And to make sure we're on the same page, could you post couple of
examples from curretly existing tests in the patch, how are they going
to look like with this proposal?
About adding variables to the FROM clause. Looks like this option was
quite popular, and you've mentioned some technical challenges
implementing that. If you'd like to go with another approach, it would
be great to elaborate on that -- maybe even with a PoC, to make a
convincing point here.
čt 14. 11. 2024 v 8:41 odesílatel Pavel Stehule <pavel.stehule@gmail.com> napsal:
st 13. 11. 2024 v 17:35 odesílatel Dmitry Dolgov <9erthalion6@gmail.com> napsal:> On Sun, Nov 10, 2024 at 06:51:40PM GMT, Pavel Stehule wrote:
> ne 10. 11. 2024 v 17:19 odesílatel Pavel Stehule <pavel.stehule@gmail.com>
> napsal:
> I thought a lot of time about better solutions for identifier collisions
> and I really don't think so there is some consistent user friendly syntax.
> Personally I think there is an easy already implemented solution -
> convention - just use a dedicated schema for variables and this schema
> should not be in the search path. Or use secondary convention - like using
> prefix "__" for session variables. Common convention is using "_" for
> PLpgSQL variables. I searched how this issue is solved in other databases,
> or in standard, and I found nothing special. The Oracle and SQL/PSM has a
> concept of visibility - the variables are not visible outside packages or
> modules, but Postgres has nothing similar. It can be emulated by a
> dedicated schema without inserting a search path, but it is less strong.
>
> I think we can introduce an alternative syntax, that will not be user
> friendly or readable friendly, but it can be without collisions - or can
> decrease possible risks.
>
> It is nothing new - SQL does it with old, "new" syntax of inner joins, or
> in Postgres we can
>
> where salary < 40000
>
> or
>
> where pg_catalog.int4lt(salary, 40000);
>
>
> or some like we use for operators OPERATOR(*schema*.*operatorname*)
>
> So introducing VARIABLE(schema.variablename) syntax as an alternative
> syntax for accessing variables I really like. I strongly prefer to use this
> as only alternative (secondary) syntax, because I don't think it is
> friendly syntax or writing friendly, but it is safe, and I can imagine
> tools that can replace generic syntax to this special, or that detects
> generic syntax and shows some warning. Then users can choose what they
> prefer. Two syntaxes - generic and special can be good enough for all - and
> this can be perfectly consistent with current Postgres.
As far as I recall, last time this topic was discussed in hackers, two
options were proposed: the one with VARIABLE(name), what you mention
here; and another one with adding variables to the FROM clause. The
VARIABLE(...) syntax didn't get much negative feedback, so I guess why
not -- if you find it fitting, it would be interesting to see the
implementation.
I'm afraid it should not be just an alternative syntax, but the only one
allowed, because otherwise I don't see how scenarious like "drop a
column with the same name" could be avoided. As in the previous thread:
-- we've got a variable b at the same time
SELECT a, b FROM table1;
Then dropping the column b, but everything still works beause the
variable b got silently picked up. But if it would be required to say
VARIABLE(b), then all fine.
In this scenario you will get a warning related to variable shadowing (before you drop a column).I think this issue can be partially similar to creating two equally named tables in different schemas (both schemas are in search path). When you drop one table, the query will work, but the result is different. It is the same issue. The SQL has no concept of shadowing and on the base line it is not necessary. But when you integrate SQL with some procedural code then you should solve this issue (or accept). This issue is real, and it is in every procedural enhancement of SQL that I know with the same syntax. On the other hand I doubt this is a real issue. The changes of system catalogue are tested before production - so probably you will read a warning about a shadowed variable, and probably you will get different results, because variable b has the same value for all rows, and probably will have different value than column b. I can imagine the necessity of disabling this warning on production systems. Shadowing by self is not an issue, probably, but it is a signal of code quality problems.But this scenario is real, and then it is a question if the warning about shadowed variables should be only optional and if it can be disabled. Maybe not. Generally the shadowing is a strange concept - it is safeguard against serious issues, but it should not be used generally and everywhere the developer should rename the conflict identifiers.
There can be another example against usage of the FROM clause for variables. Because it solves just one special case, but others are not covered.
Theoretically, variables can have the same names as tables. The table overshadows the variable, so it can work. But when somebody drops the variable, then the query still can work. So requirement of usage variable in FROM clause protects us just against drop column, but not against dropping table. In Postgres the dropping table is possibly risky due search_path (that introduces shadowing concept) without introduction variables. There is a possibility of this issue, but how common is this issue?
Regards
Pavel
RegardsPavel
And to make sure we're on the same page, could you post couple of
examples from curretly existing tests in the patch, how are they going
to look like with this proposal?
About adding variables to the FROM clause. Looks like this option was
quite popular, and you've mentioned some technical challenges
implementing that. If you'd like to go with another approach, it would
be great to elaborate on that -- maybe even with a PoC, to make a
convincing point here.
st 13. 11. 2024 v 17:35 odesílatel Dmitry Dolgov <9erthalion6@gmail.com> napsal:
> On Sun, Nov 10, 2024 at 06:51:40PM GMT, Pavel Stehule wrote:
> ne 10. 11. 2024 v 17:19 odesílatel Pavel Stehule <pavel.stehule@gmail.com>
> napsal:
> I thought a lot of time about better solutions for identifier collisions
> and I really don't think so there is some consistent user friendly syntax.
> Personally I think there is an easy already implemented solution -
> convention - just use a dedicated schema for variables and this schema
> should not be in the search path. Or use secondary convention - like using
> prefix "__" for session variables. Common convention is using "_" for
> PLpgSQL variables. I searched how this issue is solved in other databases,
> or in standard, and I found nothing special. The Oracle and SQL/PSM has a
> concept of visibility - the variables are not visible outside packages or
> modules, but Postgres has nothing similar. It can be emulated by a
> dedicated schema without inserting a search path, but it is less strong.
>
> I think we can introduce an alternative syntax, that will not be user
> friendly or readable friendly, but it can be without collisions - or can
> decrease possible risks.
>
> It is nothing new - SQL does it with old, "new" syntax of inner joins, or
> in Postgres we can
>
> where salary < 40000
>
> or
>
> where pg_catalog.int4lt(salary, 40000);
>
>
> or some like we use for operators OPERATOR(*schema*.*operatorname*)
>
> So introducing VARIABLE(schema.variablename) syntax as an alternative
> syntax for accessing variables I really like. I strongly prefer to use this
> as only alternative (secondary) syntax, because I don't think it is
> friendly syntax or writing friendly, but it is safe, and I can imagine
> tools that can replace generic syntax to this special, or that detects
> generic syntax and shows some warning. Then users can choose what they
> prefer. Two syntaxes - generic and special can be good enough for all - and
> this can be perfectly consistent with current Postgres.
As far as I recall, last time this topic was discussed in hackers, two
options were proposed: the one with VARIABLE(name), what you mention
here; and another one with adding variables to the FROM clause. The
VARIABLE(...) syntax didn't get much negative feedback, so I guess why
not -- if you find it fitting, it would be interesting to see the
implementation.
I'm afraid it should not be just an alternative syntax, but the only one
allowed, because otherwise I don't see how scenarious like "drop a
column with the same name" could be avoided. As in the previous thread:
-- we've got a variable b at the same time
SELECT a, b FROM table1;
Then dropping the column b, but everything still works beause the
variable b got silently picked up. But if it would be required to say
VARIABLE(b), then all fine.
And to make sure we're on the same page, could you post couple of
examples from curretly existing tests in the patch, how are they going
to look like with this proposal?
What do you think about the following design? I can implement a warning "variable_usage_guard" when the variable is accessed without using VARIABLE() syntax. We can discuss later if this warning can be enabled by default or not. There I am open to any variant.
So for variable public.a and table public.foo(a, b)
I can write
LET a = 10; -- there is not possible collision
LET a = a + 1; -- there is not possible collision, no warning
SELECT a, b FROM foo; -- there is a collision - and warning "variable a is shadowed"
SELECT VARIABLE(a), b FROM foo; -- no collision, no warning
After ALTER TABLE foo DROP COLUMN a;
SELECT a, b FROM foo; -- possible warning "the usage in variable without safe syntax",
SELECT VARIABLE(a), b FROM foo; -- no warning
I think this design can be good for all. variable_usage_guard can be enabled by default. If somebody uses conventions for collision protection, then he can safely disable it.
Comments, notes?
Regards
Pavel
About adding variables to the FROM clause. Looks like this option was
quite popular, and you've mentioned some technical challenges
implementing that. If you'd like to go with another approach, it would
be great to elaborate on that -- maybe even with a PoC, to make a
convincing point here.
> On Sat, Nov 16, 2024 at 07:10:31AM GMT, Pavel Stehule wrote: Sorry, got distracted. Let me try to answer step by step. > > As far as I recall, last time this topic was discussed in hackers, two > > options were proposed: the one with VARIABLE(name), what you mention > > here; and another one with adding variables to the FROM clause. The > > VARIABLE(...) syntax didn't get much negative feedback, so I guess why > > not -- if you find it fitting, it would be interesting to see the > > implementation. > > > > I'm afraid it should not be just an alternative syntax, but the only one > > allowed, because otherwise I don't see how scenarious like "drop a > > column with the same name" could be avoided. As in the previous thread: > > > > -- we've got a variable b at the same time > > SELECT a, b FROM table1; > > > > I am sorry, but I am in very strong opposition against this idea. Nobody > did reply to my questions, that can change my opinion. From your reply it's not quite clear, are you opposed to have a mandatory VARIABLE syntax, or having variables in the FROM clause? My main proposal was about the former, but the points that are following seems to talk about the latter. I think it's fine to reject the idea about the FROM clause, as long as you got some reasonable arguments. > > Then dropping the column b, but everything still works beause the > > variable b got silently picked up. But if it would be required to say > > VARIABLE(b), then all fine. > > but same risk you have any time in plpgsql - all time. I don't remember any > bug report related to this issue. Which exactly scenario about plpgsql do you have in mind? Just have tried to declare a variable inside a plpgsql function with the same name as a table column, and got an error about an ambiguous reference. > Theoretically, variables can have the same names as tables. The table > overshadows the variable, so it can work. But when somebody drops the > variable, then the query still can work. So requirement of usage variable > in FROM clause protects us just against drop column, but not against > dropping table. In Postgres the dropping table is possibly risky due > search_path (that introduces shadowing concept) without introduction > variables. There is a possibility of this issue, but how common is this > issue? This sounds to me like an argument against allowing name clashing between variables and tables. It makes even more sense, since session variables are in many ways similar to tables. > I think this issue can be partially similar to creating two equally named > tables in different schemas (both schemas are in search path). When you > drop one table, the query will work, but the result is different. It is the > same issue. The SQL has no concept of shadowing and on the base line it is > not necessary. The point is that most of users are aware about schemas and search path dangers. But to me such a precedent is not an excuse to introduce a new feature with similar traps, which folks would have to learn by making mistakes. Judging from the feedback to this patch over time, I've got an impression that lots of people are also not fans of that. > > Then dropping the column b, but everything still works beause the > > variable b got silently picked up. But if it would be required to say > > VARIABLE(b), then all fine. > > > > In this scenario you will get a warning related to variable shadowing > (before you drop a column). > > [...] > > What do you think about the following design? I can implement a warning > "variable_usage_guard" when the variable is accessed without using > VARIABLE() syntax. We can discuss later if this warning can be enabled by > default or not. There I am open to any variant. I don't follow what are you winning by that? In the context of problem above (i.e. dropping a column), such a warning is functionally equivalend to a warning about shadowing. The problem is that it doesn't sound very appealing to have a feature, which requires some extra efforts to be used in a right way (e.g. put everything into a special vars schema, or keep an eye on logs). Most certainly there are such bits in PostgreSQL today, with all the best practices, crowd wisdom, etc. But the bar for new features in this sense is much higher, you can see it from the feedback to this patch. Thus I believe it makes sense, from purely tactical reasons, to not try to convince half of the community to lower the bar, but instead try to modify the feature to make it more acceptable, even if some parts you might not like. Btw, could you repeat, what was exactly your argument against mandatory VARIABLE() syntax? It's somehow scattered across many replies, would be great to summarize it in a couple of phrases. > Shadowing by self is not an issue, probably, but it is a signal of code > quality problems. Agree, but I'm afraid code quality of an average application using PostgreSQL is quite low, so here we are. As a side note, I've recently caught myself thinking "it would be cool to have session variables here". The use case was preparing a policy for RLS, based on some session-level data set by an application. This session-level data is of a composite data type, so simple current_setting is cumbersome to use, and a temporary table will be dropped at the end, taking the policy with it due to the recorded dependency between them. Thus a session variable of some composite type sounds like a good fit.
Hi
As a side note, I've recently caught myself thinking "it would be cool to have
session variables here". The use case was preparing a policy for RLS, based on
some session-level data set by an application. This session-level data is of a
composite data type, so simple current_setting is cumbersome to use, and a
temporary table will be dropped at the end, taking the policy with it due to
the recorded dependency between them. Thus a session variable of some composite
type sounds like a good fit.
yes, RLS support is one mentioned use case, and strong reason the access rights are implemented there.
Regards
Pavel
Dmitry Dolgov: > This sounds to me like an argument against allowing name clashing between > variables and tables. It makes even more sense, since session variables are in > many ways similar to tables. +1 My mental model of a session variable is similar to a single-row, optionally global temporary, table. Is there any substantial difference that I am not aware of? Best, Wolfgang
so 16. 11. 2024 v 15:56 odesílatel Wolfgang Walther <walther@technowledgy.de> napsal:
Dmitry Dolgov:
> This sounds to me like an argument against allowing name clashing between
> variables and tables. It makes even more sense, since session variables are in
> many ways similar to tables.
+1
It doesn't help too much, because the unique tuple (schema, name), and there is a search path.
Secondly, the pg_class is not good enough for description of scalar variables, and enhancing pg_class for scalar variables can be messy.
My mental model of a session variable is similar to a single-row,
optionally global temporary, table.
Is there any substantial difference that I am not aware of?
What I know, the variables are used as query parameters, not as relations - Oracle, DB2, MSSQL, MySQL, ...
semantically, yes - it is a global temporary object, but it can be scalar or composite value - it is not row.
(global (temp)) table can hold 0, 1 or more rows (and rows are always composite of 0..n fields). The variable holds a value of some type. Proposed session variables are like plpgsql variables (only with different scope). In Postgres there is a difference between a scalar variable and composite variable with one field.
Regards
Pavel
Best,
Wolfgang
Pavel Stehule: > (global (temp)) table can hold 0, 1 or more rows (and rows are always > composite of 0..n fields). The variable holds a value of some type. > Proposed session variables are like plpgsql variables (only with > different scope). In Postgres there is a difference between a scalar > variable and composite variable with one field. I can store composite values in table columns, too. A table column can either be scalar or composite in that sense. So, maybe rephrase: Single-row, single-column (global (temp)) table = variable. One "cell" of that table. For me, the major difference between a variable and a table is, that the table has 0...n rows and 0...m columns, while the variable has *exactly* one in both cases, not 0 either. I must put tables into FROM, why not those nice mini-tables called variables as well? Because they are potentially scalar, you say! But: I can already put functions returning scalar values into FROM: SELECT * FROM format('hello'); The function returns a plain string only. I don't know. This just "fits" for me. Or to put it differently: I don't really care whether I have to write "(SELECT variable FROM variable)" instead of just "variable". I don't want session variables for the syntax, I want session variables, because they are **so much better** than custom GUCs. Best, Wolfgang
so 16. 11. 2024 v 18:13 odesílatel Wolfgang Walther <walther@technowledgy.de> napsal:
Pavel Stehule:
> (global (temp)) table can hold 0, 1 or more rows (and rows are always
> composite of 0..n fields). The variable holds a value of some type.
> Proposed session variables are like plpgsql variables (only with
> different scope). In Postgres there is a difference between a scalar
> variable and composite variable with one field.
I can store composite values in table columns, too. A table column can
either be scalar or composite in that sense.
So, maybe rephrase: Single-row, single-column (global (temp)) table =
variable. One "cell" of that table.
the tables are tables and variables are variables. For tables you have INSERT, UPDATE, DELETE commands, for variables you have a LET command.
and scalar is not a single column composite.
The session variables can in some particular use cases replace global temp tables, but this is not the goal. I would like to see global temp tables in Postgres too. Maybe session variables prepare a field for this, because some people better understand global temp objects. But again my proposal is not related to global temp tables. This is a different feature.
For me, the major difference between a variable and a table is, that the
table has 0...n rows and 0...m columns, while the variable has *exactly*
one in both cases, not 0 either.
I must put tables into FROM, why not those nice mini-tables called
variables as well? Because they are potentially scalar, you say!
But: I can already put functions returning scalar values into FROM:
SELECT * FROM format('hello');
The function returns a plain string only.
I don't know. This just "fits" for me.
There are more issues - one - when you use some composite in FROM clause, then you expect an unpacked result. But there are a lot of uses, when unpackaging is not wanted. There is a syntax for this but it is really not intuitive and not well readable.
Or to put it differently: I don't really care whether I have to write
"(SELECT variable FROM variable)" instead of just "variable". I don't
want session variables for the syntax, I want session variables, because
they are **so much better** than custom GUCs.
session variables are better than GUC for the proposed purpose. But it should look like variables. The software should respect standards or common typical usage when it is possible. If we introduce fully proprietary design, then it will be hell for all people who know any other databases. And I don't see a strong benefit from this syntax. It solves just one case, it doesn't solve other possible issues, and it introduces another possible risk.
Regards
Pavel
Best,
Wolfgang
so 16. 11. 2024 v 15:27 odesílatel Dmitry Dolgov <9erthalion6@gmail.com> napsal:
> On Sat, Nov 16, 2024 at 07:10:31AM GMT, Pavel Stehule wrote:
Sorry, got distracted. Let me try to answer step by step.
> > As far as I recall, last time this topic was discussed in hackers, two
> > options were proposed: the one with VARIABLE(name), what you mention
> > here; and another one with adding variables to the FROM clause. The
> > VARIABLE(...) syntax didn't get much negative feedback, so I guess why
> > not -- if you find it fitting, it would be interesting to see the
> > implementation.
> >
> > I'm afraid it should not be just an alternative syntax, but the only one
> > allowed, because otherwise I don't see how scenarious like "drop a
> > column with the same name" could be avoided. As in the previous thread:
> >
> > -- we've got a variable b at the same time
> > SELECT a, b FROM table1;
> >
>
> I am sorry, but I am in very strong opposition against this idea. Nobody
> did reply to my questions, that can change my opinion.
From your reply it's not quite clear, are you opposed to have a mandatory
VARIABLE syntax, or having variables in the FROM clause? My main proposal was
about the former, but the points that are following seems to talk about the
latter. I think it's fine to reject the idea about the FROM clause, as long as
you got some reasonable arguments.
I am against a requirement to specify a variable in the FROM clause.
> > Then dropping the column b, but everything still works beause the
> > variable b got silently picked up. But if it would be required to say
> > VARIABLE(b), then all fine.
>
> but same risk you have any time in plpgsql - all time. I don't remember any
> bug report related to this issue.
Which exactly scenario about plpgsql do you have in mind? Just have tried to
declare a variable inside a plpgsql function with the same name as a table
column, and got an error about an ambiguous reference.
Until you execute the query, you cannot know if there is a conflict or not. So you can change table structure and you can change the procedure's code, and there can be an invisible conflict until execution and query evaluation. The conflict between PL/pgSQL and SQL raises an error. The conflict between session variables and SQL raises warnings. The issue is detected.
> Theoretically, variables can have the same names as tables. The table
> overshadows the variable, so it can work. But when somebody drops the
> variable, then the query still can work. So requirement of usage variable
> in FROM clause protects us just against drop column, but not against
> dropping table. In Postgres the dropping table is possibly risky due
> search_path (that introduces shadowing concept) without introduction
> variables. There is a possibility of this issue, but how common is this
> issue?
This sounds to me like an argument against allowing name clashing between
variables and tables. It makes even more sense, since session variables are in
many ways similar to tables.
It doesn't help too much. It can fix just one issue. But you can have tables with the same name in different schemas inside schemas from search_path. Unique table names solve nothing.
> I think this issue can be partially similar to creating two equally named
> tables in different schemas (both schemas are in search path). When you
> drop one table, the query will work, but the result is different. It is the
> same issue. The SQL has no concept of shadowing and on the base line it is
> not necessary.
The point is that most of users are aware about schemas and search path
dangers. But to me such a precedent is not an excuse to introduce a new feature
with similar traps, which folks would have to learn by making mistakes. Judging
from the feedback to this patch over time, I've got an impression that lots of
people are also not fans of that.
Unfortunately - I don't believe so there is some syntax without traps. You can check all implementations in other databases. These designs are very different, and all have some issues and all have some limits. It is native - you are trying to join the procedural and functional world.
I understand the risks. These risks are there. But there is no silver bullet - all proposed designs fixed just one case, and not others, and then I don't see a strong enough benefit to introduce design that is far from common usage. Maybe I have a different experience, because I am a man from the stored procedures area, and the risk of collisions is a known issue well solved by common conventions and in postgres by plpgsql.variable_conflict setting. The proposed patch set has very similar functionality. I think the introduction of VARIABLE(xx) syntax and safe syntax guard warning the usage of variables can be safe in how it is possible. But still I want to allow "short" "usual" usage to people who use a safe convention. There is no risk when you use a safe prefix or safe schema.
> > Then dropping the column b, but everything still works beause the
> > variable b got silently picked up. But if it would be required to say
> > VARIABLE(b), then all fine.
> >
>
> In this scenario you will get a warning related to variable shadowing
> (before you drop a column).
>
> [...]
>
> What do you think about the following design? I can implement a warning
> "variable_usage_guard" when the variable is accessed without using
> VARIABLE() syntax. We can discuss later if this warning can be enabled by
> default or not. There I am open to any variant.
I don't follow what are you winning by that? In the context of problem above
(i.e. dropping a column), such a warning is functionally equivalend to a
warning about shadowing.
The problem is that it doesn't sound very appealing to have a feature, which
requires some extra efforts to be used in a right way (e.g. put everything into
a special vars schema, or keep an eye on logs). Most certainly there are such
bits in PostgreSQL today, with all the best practices, crowd wisdom, etc. But
the bar for new features in this sense is much higher, you can see it from the
feedback to this patch. Thus I believe it makes sense, from purely tactical
reasons, to not try to convince half of the community to lower the bar, but
instead try to modify the feature to make it more acceptable, even if some
parts you might not like.
Btw, could you repeat, what was exactly your argument against mandatory
VARIABLE() syntax? It's somehow scattered across many replies, would be great
to summarize it in a couple of phrases.
> Shadowing by self is not an issue, probably, but it is a signal of code
> quality problems.
Agree, but I'm afraid code quality of an average application using PostgreSQL
is quite low, so here we are.
As a side note, I've recently caught myself thinking "it would be cool to have
session variables here". The use case was preparing a policy for RLS, based on
some session-level data set by an application. This session-level data is of a
composite data type, so simple current_setting is cumbersome to use, and a
temporary table will be dropped at the end, taking the policy with it due to
the recorded dependency between them. Thus a session variable of some composite
type sounds like a good fit.
so 16. 11. 2024 v 23:49 odesílatel Pavel Stehule <pavel.stehule@gmail.com> napsal:
so 16. 11. 2024 v 15:27 odesílatel Dmitry Dolgov <9erthalion6@gmail.com> napsal:> On Sat, Nov 16, 2024 at 07:10:31AM GMT, Pavel Stehule wrote:
Sorry, got distracted. Let me try to answer step by step.
> > As far as I recall, last time this topic was discussed in hackers, two
> > options were proposed: the one with VARIABLE(name), what you mention
> > here; and another one with adding variables to the FROM clause. The
> > VARIABLE(...) syntax didn't get much negative feedback, so I guess why
> > not -- if you find it fitting, it would be interesting to see the
> > implementation.
> >
> > I'm afraid it should not be just an alternative syntax, but the only one
> > allowed, because otherwise I don't see how scenarious like "drop a
> > column with the same name" could be avoided. As in the previous thread:
> >
> > -- we've got a variable b at the same time
> > SELECT a, b FROM table1;
> >
>
> I am sorry, but I am in very strong opposition against this idea. Nobody
> did reply to my questions, that can change my opinion.
From your reply it's not quite clear, are you opposed to have a mandatory
VARIABLE syntax, or having variables in the FROM clause? My main proposal was
about the former, but the points that are following seems to talk about the
latter. I think it's fine to reject the idea about the FROM clause, as long as
you got some reasonable arguments.I am against a requirement to specify a variable in the FROM clause.
> > Then dropping the column b, but everything still works beause the
> > variable b got silently picked up. But if it would be required to say
> > VARIABLE(b), then all fine.
>
> but same risk you have any time in plpgsql - all time. I don't remember any
> bug report related to this issue.
Which exactly scenario about plpgsql do you have in mind? Just have tried to
declare a variable inside a plpgsql function with the same name as a table
column, and got an error about an ambiguous reference.Until you execute the query, you cannot know if there is a conflict or not. So you can change table structure and you can change the procedure's code, and there can be an invisible conflict until execution and query evaluation. The conflict between PL/pgSQL and SQL raises an error. The conflict between session variables and SQL raises warnings. The issue is detected.
> Theoretically, variables can have the same names as tables. The table
> overshadows the variable, so it can work. But when somebody drops the
> variable, then the query still can work. So requirement of usage variable
> in FROM clause protects us just against drop column, but not against
> dropping table. In Postgres the dropping table is possibly risky due
> search_path (that introduces shadowing concept) without introduction
> variables. There is a possibility of this issue, but how common is this
> issue?
This sounds to me like an argument against allowing name clashing between
variables and tables. It makes even more sense, since session variables are in
many ways similar to tables.It doesn't help too much. It can fix just one issue. But you can have tables with the same name in different schemas inside schemas from search_path. Unique table names solve nothing.
the combination of pg_class and pg_attribute cannot describe scalar variables (without hacks). Then you need to enhance pg_class, which can be confusing. And on the second hand almost all columns in pg_class have no sense for variables. And when variables and tables are in different tables, you cannot ensure a unique name. Variables are similar to tables only in possibility to hold a value. That is all. But variables don't store data to file, don't store data in pages, don't allow usage of other storages or formats, and don't support foreign storage. The similarity between variables and tables is like the similarity between horses and cars. Both can help with moving.
> I think this issue can be partially similar to creating two equally named
> tables in different schemas (both schemas are in search path). When you
> drop one table, the query will work, but the result is different. It is the
> same issue. The SQL has no concept of shadowing and on the base line it is
> not necessary.
The point is that most of users are aware about schemas and search path
dangers. But to me such a precedent is not an excuse to introduce a new feature
with similar traps, which folks would have to learn by making mistakes. Judging
from the feedback to this patch over time, I've got an impression that lots of
people are also not fans of that.Unfortunately - I don't believe so there is some syntax without traps. You can check all implementations in other databases. These designs are very different, and all have some issues and all have some limits. It is native - you are trying to join the procedural and functional world.I understand the risks. These risks are there. But there is no silver bullet - all proposed designs fixed just one case, and not others, and then I don't see a strong enough benefit to introduce design that is far from common usage. Maybe I have a different experience, because I am a man from the stored procedures area, and the risk of collisions is a known issue well solved by common conventions and in postgres by plpgsql.variable_conflict setting. The proposed patch set has very similar functionality. I think the introduction of VARIABLE(xx) syntax and safe syntax guard warning the usage of variables can be safe in how it is possible. But still I want to allow "short" "usual" usage to people who use a safe convention. There is no risk when you use a safe prefix or safe schema.
> > Then dropping the column b, but everything still works beause the
> > variable b got silently picked up. But if it would be required to say
> > VARIABLE(b), then all fine.
> >
>
> In this scenario you will get a warning related to variable shadowing
> (before you drop a column).
>
> [...]
>
> What do you think about the following design? I can implement a warning
> "variable_usage_guard" when the variable is accessed without using
> VARIABLE() syntax. We can discuss later if this warning can be enabled by
> default or not. There I am open to any variant.
I don't follow what are you winning by that? In the context of problem above
(i.e. dropping a column), such a warning is functionally equivalend to a
warning about shadowing.
The problem is that it doesn't sound very appealing to have a feature, which
requires some extra efforts to be used in a right way (e.g. put everything into
a special vars schema, or keep an eye on logs). Most certainly there are such
bits in PostgreSQL today, with all the best practices, crowd wisdom, etc. But
the bar for new features in this sense is much higher, you can see it from the
feedback to this patch. Thus I believe it makes sense, from purely tactical
reasons, to not try to convince half of the community to lower the bar, but
instead try to modify the feature to make it more acceptable, even if some
parts you might not like.
Btw, could you repeat, what was exactly your argument against mandatory
VARIABLE() syntax? It's somehow scattered across many replies, would be great
to summarize it in a couple of phrases.
> Shadowing by self is not an issue, probably, but it is a signal of code
> quality problems.
Agree, but I'm afraid code quality of an average application using PostgreSQL
is quite low, so here we are.
As a side note, I've recently caught myself thinking "it would be cool to have
session variables here". The use case was preparing a policy for RLS, based on
some session-level data set by an application. This session-level data is of a
composite data type, so simple current_setting is cumbersome to use, and a
temporary table will be dropped at the end, taking the policy with it due to
the recorded dependency between them. Thus a session variable of some composite
type sounds like a good fit.
so 16. 11. 2024 v 23:07 odesílatel Pavel Stehule <pavel.stehule@gmail.com> napsal:
so 16. 11. 2024 v 18:13 odesílatel Wolfgang Walther <walther@technowledgy.de> napsal:Pavel Stehule:
> (global (temp)) table can hold 0, 1 or more rows (and rows are always
> composite of 0..n fields). The variable holds a value of some type.
> Proposed session variables are like plpgsql variables (only with
> different scope). In Postgres there is a difference between a scalar
> variable and composite variable with one field.
I can store composite values in table columns, too. A table column can
either be scalar or composite in that sense.
So, maybe rephrase: Single-row, single-column (global (temp)) table =
variable. One "cell" of that table.the tables are tables and variables are variables. For tables you have INSERT, UPDATE, DELETE commands, for variables you have a LET command.and scalar is not a single column composite.
example
assignment to scalar versus single composite
LET a = 10
LET a.a = 10 or LET a = ROW(10)
Single column tables can be the result of some ALTERS - or sometimes you can use a table type. But for example, plpgsql, very strongly differs between scalar and composite variables. So introducing the "new" concept - single field composite is scalar introduces strong inconsistency there.
Regards
Pavel
The session variables can in some particular use cases replace global temp tables, but this is not the goal. I would like to see global temp tables in Postgres too. Maybe session variables prepare a field for this, because some people better understand global temp objects. But again my proposal is not related to global temp tables. This is a different feature.
For me, the major difference between a variable and a table is, that the
table has 0...n rows and 0...m columns, while the variable has *exactly*
one in both cases, not 0 either.
I must put tables into FROM, why not those nice mini-tables called
variables as well? Because they are potentially scalar, you say!
But: I can already put functions returning scalar values into FROM:
SELECT * FROM format('hello');
The function returns a plain string only.
I don't know. This just "fits" for me.There are more issues - one - when you use some composite in FROM clause, then you expect an unpacked result. But there are a lot of uses, when unpackaging is not wanted. There is a syntax for this but it is really not intuitive and not well readable.
Or to put it differently: I don't really care whether I have to write
"(SELECT variable FROM variable)" instead of just "variable". I don't
want session variables for the syntax, I want session variables, because
they are **so much better** than custom GUCs.session variables are better than GUC for the proposed purpose. But it should look like variables. The software should respect standards or common typical usage when it is possible. If we introduce fully proprietary design, then it will be hell for all people who know any other databases. And I don't see a strong benefit from this syntax. It solves just one case, it doesn't solve other possible issues, and it introduces another possible risk.RegardsPavel
Best,
Wolfgang
Em ter., 19 de nov. de 2024 às 16:15, Pavel Stehule <pavel.stehule@gmail.com> escreveu:
I wrote POC of VARIABLE(varname) syntax support
Not related with POC of VARIABLE but seeing your patches ...
Wouldn't it be better to use just one syntax and message for what to do ON COMMIT ?
When creating a new variable you use
CREATE VARIABLE ... ON COMMIT DROP | ON TRANSACTION END RESET
On PSQL \dV+ you show
Transactional end action
Maybe all them could be just ON COMMIT
CREATE VARIABLE ... [ON COMMIT {NO ACTION, DROP, RESET}] and \dV+ just "on commit" on title column
regards
Marcos
Hi
st 20. 11. 2024 v 14:29 odesílatel Marcos Pegoraro <marcos@f10.com.br> napsal:
Em ter., 19 de nov. de 2024 às 16:15, Pavel Stehule <pavel.stehule@gmail.com> escreveu:I wrote POC of VARIABLE(varname) syntax supportNot related with POC of VARIABLE but seeing your patches ...Wouldn't it be better to use just one syntax and message for what to do ON COMMIT ?When creating a new variable you useCREATE VARIABLE ... ON COMMIT DROP | ON TRANSACTION END RESETOn PSQL \dV+ you showTransactional end actionMaybe all them could be just ON COMMITCREATE VARIABLE ... [ON COMMIT {NO ACTION, DROP, RESET}] and \dV+ just "on commit" on title column
ON COMMIT DROP is related to temporary objects. In this case, you don't need to think about ROLLBACK, because in this case, the temp objects are removed implicitly.
ON TRANSACTION END RESET can be used for non temporary objects too. So this is a little bit of a different feature. But the reset is executed if the transaction is ended by ROLLBACK too. So using a syntax just ON COMMIT can be a little bit messy. TRANSACTION END is more intuitive, I think. If I remember there was a proposal ON COMMIT OR ROLLBACK, but I think TRANSACTION END is better and more intuitive, and better describes what is implemented. I can imagine to support clauses ON COMMIT RESET or ON ROLLBACK RESET that can be used independently, but for this time, I don't want to increase a complexity now - reset is just at transaction end without dependency if the transaction was committed or rollbacked.
Regards
Pavel
regardsMarcos
Em qua., 20 de nov. de 2024 às 10:52, Pavel Stehule <pavel.stehule@gmail.com> escreveu:
COMMIT can be a little bit messy. TRANSACTION END is more intuitive, I think.
Exactly to be not messy I would just ON COMMIT for all, and DOCs can explain that this option is ignored for temp objects and do the same at the end of transaction, independently if commited or rolled back
st 20. 11. 2024 v 15:15 odesílatel Marcos Pegoraro <marcos@f10.com.br> napsal:
Em qua., 20 de nov. de 2024 às 10:52, Pavel Stehule <pavel.stehule@gmail.com> escreveu:COMMIT can be a little bit messy. TRANSACTION END is more intuitive, I think.Exactly to be not messy I would just ON COMMIT for all, and DOCs can explain that this option is ignored for temp objects and do the same at the end of transaction, independently if commited or rolled back
I feel it differently - when I read ON COMMIT, then I expect really just a COMMIT event, not ROLLBACK. Attention - the metadata about variables are transactional, but the variables are not transactional (by default).
But this feeling can be subjective. The objective argument against using ON COMMIT like ON TRANSACTION END is fact, so we lost a possibility for a more precious setting.
I can imagine scenarios with ON COMMIT RESET - and variable can hold some last value from transaction, or ON ROLLBACK RESET - and variable can hold some computed value from successfully ended transaction - last inserted id.
In this case, I don't see a problem to reopen a discussion about syntax or postpone this feature. I think the possibility to reset variables at some specified time can be an interesting feature (that can increase safety, because the application doesn't need to solve initial setup), but from the list of implemented features for session variables, this is not too far from the end. If TRANSACTION END is not intuitive - with exactly the same functionality can be RESET AT TRANSACTION START - so the ON TRANSACTION END can be transformed to ON BEGIN RESET, and this syntax can be maybe better, because it signalize, for every transaction, the variable will be initialized to default. What do you think? Can be ON BEGIN RESET acceptable for you.
Regards
Pavel
> On Tue, Nov 19, 2024 at 08:14:01PM +0100, Pavel Stehule wrote: > Hi > > I wrote POC of VARIABLE(varname) syntax support Thanks, the results look good. I'm still opposed the idea of having a warning, and think it has to be an error -- but it's my subjective opinion. Lets see if there are more votes on that topic.
st 20. 11. 2024 v 21:14 odesílatel Dmitry Dolgov <9erthalion6@gmail.com> napsal:
> On Tue, Nov 19, 2024 at 08:14:01PM +0100, Pavel Stehule wrote:
> Hi
>
> I wrote POC of VARIABLE(varname) syntax support
Thanks, the results look good. I'm still opposed the idea of having a
warning, and think it has to be an error -- but it's my subjective
opinion. Lets see if there are more votes on that topic.
The error breaks the possibility to use variables (session variables) like Oracle's package variables easily. It increases effort for transformation or porting because you should identify variables inside queries and you should wrap it to fence. On the other hand, extensions that can read a query after transformation can easily detect unwrapped variables and they can raise an error. It can be very easy to implement this check to plpgsql_check for example or like plpgsql.extra_check.
In my ideal world, the shadowing warning should be enabled by default, and an unfencing warning disabled by default. But I have not a problem with activating both warnings by default. I think warnings are enough, because if there is some risk then a shadowing warning is activated. And my experience is more positive about warnings, people read it.
Regards
Pavel
On Thu, Dec 5, 2024 at 2:52 PM Pavel Stehule <pavel.stehule@gmail.com> wrote: > > Hi > > only rebase hi. disclaimer, i *only* applied v20241205-0001-Enhancing-catalog-for-support-session-variables-and-.patch. create variable v2 as text; alter variable v2 rename to v2; ERROR: session variable "v2" already exists in schema "public" the above is coverage tests for report_namespace_conflict: case VariableRelationId: Assert(OidIsValid(nspOid)); msgfmt = gettext_noop("session variable \"%s\" already exists in schema \"%s\""); break; create type t1 as (a int, b int); CREATE VARIABLE var1 AS t1; alter type t1 drop attribute a; should "alter type t1 drop attribute a;" not allowed? GetCommandLogLevel also needs to deal with case T_CreateSessionVarStmt? there are no regress tests for the change we made in find_composite_type_dependencies? It looks like it will be reachable for sure. CreateVariable, print out error position: if (get_typtype(typid) == TYPTYPE_PSEUDO) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("session variable cannot be pseudo-type %s", format_type_be(typid)), parser_errposition(pstate, stmt->typeName->location))); Alvaro Herrera told me actually, you don't need the extra parentheses around errcode. so you can: if (get_typtype(typid) == TYPTYPE_PSEUDO) ereport(ERROR, errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("session variable cannot be pseudo-type %s", format_type_be(typid)), parser_errposition(pstate, stmt->typeName->location)) pg_variable_is_visible seems to have done twice the system cache call. maybe follow through with the pg_table_is_visible, pg_type_is_visible code pattern. IN src/bin/psql/describe.c + appendPQExpBufferStr(&buf, "\nWHERE true\n"); this is not needed? ------------------------------------------------ some of the `foreach` can change to foreach_oid, foreach_node see: https://git.postgresql.org/cgit/postgresql.git/commit/?id=14dd0f27d7cd56ffae9ecdbe324965073d01a9ff ------------------------------------------------ doc/src/sgml/ref/create_variable.sgml <programlisting> CREATE VARIABLE var1 AS date; LET var1 = current_date; SELECT var1; </programlisting> v20241205-0001-Enhancing-catalog-for-support-session-variables-and-.patch alone cannot do `LET var1 = current_date;`, `SELECT var1;` maybe the following patch can do it. but that makes we cannot commit v20241205-0001-Enhancing-catalog-for-support-session-variables-and-.patch alone. ------------------------------------------------ since CREATE VARIABLE is an extension to standard, so in create_schema.sgml Compatibility section, do we need to mention CREATE SCHEMA CREATE VARIABLE is an extension from standard ? ----------------------------------------------- /* * Drop variable by OID, and register the needed session variable * cleanup. */ void DropVariableById(Oid varid) i am not sure of the meaning of "register the needed session variable cleanup".
On Mon, Dec 9, 2024 at 2:33 AM Pavel Stehule <pavel.stehule@gmail.com> wrote: > > Hi > again. only applied v20241208-0001-Enhancing-catalog-for-support-session-variables-and-.patch. /* we want SessionVariableCreatePostprocess to see the catalog changes. */ 0001 doesn't have SessionVariableCreatePostprocess, so this comment is wrong in the context of 0001. typo: As above, but if the variable isn't found and is_mussing is not NULL is_mussing should be is_missing. ---------------------------------------------- issue with grant.sgml and revoke.sgml. * there are no regress tests for WITH GRANT OPTION but it seems to work; there are no REVOKE CASCADE tests. the following tests show REVOKE CASCADE works. create variable v1 as int; GRANT select on VARIABLE v1 to alice with grant option; set session authorization alice; GRANT select on VARIABLE v1 to bob with grant option; reset session authorization; select varacl from pg_variable where varname = 'v1'; --output {jian=rw/jian,alice=r*/jian,bob=r*/alice} revoke all privileges on variable v1 from alice cascade; select varacl from pg_variable where varname = 'v1'; --output {jian=rw/jian} revoke GRANT OPTION FOR all privileges on variable v1 from alice cascade; also works. * in revoke.sgml and grant.sgml. if you look closely, " | ALL VARIABLES IN SCHEMA schema_name [, ...] }" is wrong because there is no left-curly-bracket, but there is a right-curly-bracket. * in revoke.sgml. <phrase>where <replaceable class="parameter">role_specification</replaceable> can be:</phrase> [ GROUP ] <replaceable class="parameter">role_name</replaceable> | PUBLIC | CURRENT_ROLE | CURRENT_USER | SESSION_USER should be at the end of the synopsis section? otherwise it looks weird, maybe we can put the REVOKE VARIABLE code upper. grant.sgml changes position looks fine to me. * <para> The <command>GRANT</command> command has two basic variants: one that grants privileges on a database object (table, column, view, foreign table, sequence, database, foreign-data wrapper, foreign server, function, procedure, procedural language, large object, configuration parameter, schema, tablespace, or type), and one that grants membership in a role. These variants are similar in many ways, but they are different enough to be described separately. </para> this <para> in grant.sgml needs to also mention "variable"? * <para> Privileges on databases, tablespaces, schemas, languages, and configuration parameters are <productname>PostgreSQL</productname> extensions. </para> this <para> in grant.sgml needs to also mention "variable"? ---------------------------------------------- * + <para> + Inside a query or an expression, a session variable can be + <quote>shadowed</quote> by a column with the same name. Similarly, the + name of a function or procedure argument or a PL/pgSQL variable (see PL/pgSQL should decorated as <application>PL/pgSQL</application> * we already support \dV and \dV+ in v20241208-0001-Enhancing-catalog-for-support-session-variables-and-.patch so we should update doc/src/sgml/ref/psql-ref.sgml also. I briefly searched \dV in v20241208-0002-Storage-for-session-variables-and-SQL-interface.patch, no entry. * in doc/src/sgml/ddl.sgml <table id="privilege-abbrevs-table"> and <table id="privileges-summary-table"> need to change for variable? <varlistentry id="ddl-priv-select">, <varlistentry id="ddl-priv-update"> need to change for variable? it's kind of tricky. if we only apply v20241208-0001-Enhancing-catalog-for-support-session-variables-and-.patch we can not SELECT or UPDATE variable. so how are we going to mention these privileges for variable? * we can add some tests for EVENT TRIGGER test, since event trigger support CREATE|DROP variable. atually, I think there is a bug. create variable v1 as int; CREATE OR REPLACE FUNCTION event_trigger_report_dropped() RETURNS event_trigger LANGUAGE plpgsql AS $$ DECLARE r record; BEGIN FOR r IN SELECT * from pg_event_trigger_dropped_objects() LOOP IF NOT r.normal AND NOT r.original THEN CONTINUE; END IF; RAISE NOTICE 'NORMAL: orig=% normal=% istemp=% type=% identity=% name=% args=%', r.original, r.normal, r.is_temporary, r.object_type, r.object_identity, r.address_names, r.address_args; END LOOP; END; $$; CREATE EVENT TRIGGER regress_event_trigger_report_dropped ON sql_drop WHEN TAG IN ('DROP VARIABLE') EXECUTE PROCEDURE event_trigger_report_dropped(); --output: src9=# drop variable v1; NOTICE: test_event_trigger: ddl_command_start DROP VARIABLE NOTICE: NORMAL: orig=t normal=f istemp=f type=session variable identity=public.v1 name={public,$} args={} DROP VARIABLE should i expect NOTICE: NORMAL: orig=t normal=f istemp=f type=session variable identity=public.v1 name={public,$} args={} to be NOTICE: NORMAL: orig=t normal=f istemp=f type=session variable identity=public.v1 name={public,v1} args={} ?
Hi
st 20. 11. 2024 v 21:14 odesílatel Dmitry Dolgov <9erthalion6@gmail.com> napsal:
> On Tue, Nov 19, 2024 at 08:14:01PM +0100, Pavel Stehule wrote:
> Hi
>
> I wrote POC of VARIABLE(varname) syntax support
Thanks, the results look good. I'm still opposed the idea of having a
warning, and think it has to be an error -- but it's my subjective
opinion. Lets see if there are more votes on that topic.
Maybe the warning of usage of unfenced variables can be changed (enhanced) to some different mechanism that can be more restrictive (and safer), but I think it can still be user friendly.
My idea is based on assumption so users with knowledge of stored procedures know variables and related risks (and know tools how to minimize risks), and for other people the risk is higher and we should force usage of variable fences. I think we can force usage of variable fences at query runtime, when query is not executed from the SPI environment. This behaviour can be enabled by default, but can be optionally disabled.
CREATE VARIABLE s.x AS int; -- allowed when user has create right on schema s
CREATE VIEW v1 AS SELECT x; -- no problem, the check is dynamic (execution), not static
CREATE VIEW v2 AS SELECT VARIABLE(x); -- no problem
SELECT x; -- fails on access to unfenced variable
SELECT * FROM v1; -- fails on access to unfenced variable
SELECT * FROM v2; -- ok
but inside pl, this check will not be active, and then with default setting I can write an code like
LET var = 10; -- fencing is not allowed there, and there is not any collision
DO $$
BEGIN
RAISE NOTICE 'var=%', var;
RAISE NOTICE 'var=%', (SELECT * FROM v1); --is ok here too
END;
$$;
Outside PL the fencing can be required, inside PL the fencing can be optional. With this proposal we can limit the possible risk usage of unfenced variables only in PL context, and the behaviour can be very similar to PL/SQL or SQL/PSM. This check is only a runtime check, so it has no impact on any DDL statement. It doesn't change the syntax or behavior, so it can be implemented subsequently - it is just a safeguard against unwanted usage of variables in an environment, where users have no possibility to use variables already. I can imagine that this check "allow_unfenced_variables" can have three values (everywhere, pl, nowhere) and the default can be pl. The results of queries don't depend on the current setting of this check. For all values for all possible queries and situations, the result is the same (when it is finished). But sometimes, the check can break the execution - in similar meaning like access rights. All previous proposed warnings can be unchanged.
Comments, notes?
Regards
Pavel
hi. GRANT|REVOKE ALL VARIABLES IN SCHEMA schema_name [, ...] } seems to work. might be better to add tests. also src/bin/psql/tab-complete.in.c COMPLETE_WITH_SCHEMA_QUERY_PLUS(Query_for_list_of_grantables, we can also add "ALL VARIABLES IN SCHEMA " also need change this <para> in grant.sgml: <para> There is also an option to grant privileges on all objects of the same type within one or more schemas. This functionality is currently supported only for tables, sequences, functions, and procedures. <literal>ALL TABLES</literal> also affects views and foreign tables, just like the specific-object <command>GRANT</command> command. <literal>ALL FUNCTIONS</literal> also affects aggregate and window functions, but not procedures, again just like the specific-object <command>GRANT</command> command. Use <literal>ALL ROUTINES</literal> to include procedures. </para> revoke.sgml, we should use <replaceable class="parameter">role_specification</replaceable>? so it will become like: REVOKE [ GRANT OPTION FOR ] { { SELECT | UPDATE } [, ...] | ALL [ PRIVILEGES ] } ON { VARIABLE variable_name [, ...] | ALL VARIABLES IN SCHEMA schema_name [, ...] } FROM role_specification [, ...] maybe also add [ GRANTED BY role_specification ] but I didn't test "REVOKE [ GRANTED BY role_specification ]". Speaking of acl tests, similar to has_table_privilege I am afraid we need to have a function like has_variable_privilege for acl tests. has_table_privilege has 6 function signatures. so there will be more code. ------------------------------------------------------ doc/src/sgml/ref/create_variable.sgml <synopsis> section: CREATE VARIABLE [ IF NOT EXISTS ] name [ AS ] data_type ] [ COLLATE collation ] redundant right square bracket after "data_type".
hi. /* * has_session_variable_privilege variants * These are all named "has_session_variable_privilege" at the SQL level. * They take various combinations of variable name, variable OID, * user name, user OID, or implicit user = current_user. * * The result is a boolean value: true if user has the indicated * privilege, false if not. The variants that take a relation OID * return NULL if the OID doesn't exist. */ /* * has_session_variable_privilege_name_name * Check user privileges on a session variable given * name username, text sessin variable name, and text priv name. */ "The variants that take a relation OID return NULL if the OID doesn't exist." should it be "The variants that take an OID type return NULL if the OID doesn't exist." ? typo, "sessin" should be "session". ----------------<<<>>>>------------------- <sect1 id="ddl-session-variables"> <title>Session Variables</title> only mentioned that "Session variables themselves are persistent, but their values are neither persistent nor shared (like the content of temporary tables). " I feel like this sentence is not that explicit. we actually want to say "Once a session exits, the variable value is reset to NULL, one session cannot see another session variable value." + <para> + A persistent database object that holds a value in session memory. This + value is private to each session and is released when the session ends. + Read or write access to session variables is controlled by privileges, + similar to other database objects. + </para> i do like this description in glossary.sgml. maybe we can copy it and put it to ddl.sgml "<sect1 id="ddl-session-variables"> ----------------<<<>>>>------------------- REVOKE [ GRANT OPTION FOR ] { { SELECT | UPDATE } [, ...] | ALL [ PRIVILEGES ] } ON { VARIABLE <replaceable>variable_name</replaceable> [, ...] | ALL VARIABLES IN SCHEMA <replaceable class="parameter">schema_name</replaceable> [, ...] } FROM { [ GROUP ] <replaceable class="parameter">role_specification</replaceable> | PUBLIC } [, ...] [ GRANTED BY <replaceable class="parameter">role_specification</replaceable> ] [ CASCADE | RESTRICT ] revoke, seems still not right. since with this, we can say: REVOKE ALL PRIVILEGES ON VARIABLE v1 FROM group group alice CASCADE; i think the correct one should be: REVOKE [ GRANT OPTION FOR ] { { SELECT | UPDATE } [, ...] | ALL [ PRIVILEGES ] } ON { VARIABLE <replaceable>variable_name</replaceable> [, ...] | ALL VARIABLES IN SCHEMA <replaceable class="parameter">schema_name</replaceable> [, ...] } FROM <replaceable class="parameter">role_specification</replaceable> [, ...] [ GRANTED BY <replaceable class="parameter">role_specification</replaceable> ] [ CASCADE | RESTRICT ] ----------------<<<>>>>------------------- <programlisting> CREATE VARIABLE public.current_user_id AS integer; GRANT READ ON VARIABLE public.current_user_id TO PUBLIC; LET current_user_id = (SELECT id FROM users WHERE usename = session_user); SELECT current_user_id; </programlisting> "GRANT READ" should be "GRANT SELECT". ----------------<<<>>>>------------------- doc/src/sgml/ref/alter_default_privileges.sgml GRANT { SELECT | UPDATE | ALL [ PRIVILEGES ] } ON VARIABLES TO { [ GROUP ] <replaceable class="parameter">role_name</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ] the above part is wrong? should be: GRANT { { SELECT | UPDATE } [,...] | ALL [ PRIVILEGES ] } ON VARIABLES TO { [ GROUP ] <replaceable class="parameter">role_name</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ] since we can: ALTER DEFAULT PRIVILEGES FOR ROLE alice IN SCHEMA svartest GRANT SELECT, UPDATE ON VARIABLES TO bob; ----------------<<<>>>>----------------------------- CREATE VARIABLE IF NOT EXISTS v2 AS comp; grant update on variable v2 to alice; set role alice; LET v2.a = 12; --acl permission error LET v2.b = 12; --acl permission error LET v2 = (11,12); --ok. not sure this is the desired behavior, for composite type variables, you are allowed to change all the values, but you are not allowed to update the field value of the composite. The following are normal table test update cases. create type comp as (a int, b int); create table t2(a comp); insert into t2 select '(11,12)'; grant update (a ) on t2 to alice; set role alice; update t2 set a.a = 13; --ok update t2 set a.b = 13; --ok update t2 set a = '(11,13)'; --ok ----------------<<<>>>>----------------------------- domain seems to have an issue. CREATE domain d1 AS int; CREATE VARIABLE var1 AS d1; let var1 = 3; --this should fail?. alter domain d1 add check (value <> 3); select var1; ERROR: value for domain d1 violates check constraint "d1_check" ----------------<<<>>>>----------------------------- doc/src/sgml/ref/alter_variable.sgml <title>Parameters</title> section, the order should be: name, new_owner, new_name, new_schema? I am beginning to look around 0002.
hi. review is based on v20241219-0002-Storage-for-session-variables-and-SQL-interface.patch and v20241219-0001-Enhancing-catalog-for-support-session-variables-and-.patch. in doc/src/sgml/catalogs.sgml <row> <entry role="catalog_table_entry"><para role="column_definition"> <structfield>defaclobjtype</structfield> <type>char</type> </para> <para> Type of object this entry is for: <literal>r</literal> = relation (table, view), <literal>S</literal> = sequence, <literal>f</literal> = function, <literal>T</literal> = type, <literal>n</literal> = schema </para></entry> </row> this need updated for session variable? psql meta command \ddp src/bin/psql/describe.c listDefaultACLs also need to change. ----------------<<>>------------------------- +-- show variable +SELECT public.svar; +SELECT public.svar.c; +SELECT (public.svar).*; + +-- the variable is shadowed, raise error +SELECT public.svar.c FROM public.svar; + +-- can be fixed by alias +SELECT public.svar.c FROM public.svar x The above tests are duplicated in session_variables.sql. ----------------<<>>------------------------- --- a/src/include/nodes/plannodes.h +++ b/src/include/nodes/plannodes.h @@ -49,7 +49,7 @@ typedef struct PlannedStmt NodeTag type; - CmdType commandType; /* select|insert|update|delete|merge|utility */ + CmdType commandType; /* select|let|insert|update|delete|merge|utility */ since we don't have CMD_LET CmdType. so this comment change is not necessary? ----------------<<>>------------------------- the following are simple tests that triggers makeParamSessionVariable error messages. we don't have related tests, we can add it on session_variables.sql. create type t1 as (a int, b int); CREATE VARIABLE v1 text; CREATE VARIABLE v2 as t1; select v1.a; select v2.c; also select v2.c; ERROR: could not identify column "c" in variable LINE 1: select v2.c; ^ the error message is no good. i think we want: ERROR: could not identify column "c" in variable "public.v1" ----------------<<>>------------------------- + /* + * Check for duplicates. Note that this does not really prevent + * duplicates, it's here just to provide nicer error message in common + * case. The real protection is the unique key on the catalog. + */ + if (SearchSysCacheExists2(VARIABLENAMENSP, + PointerGetDatum(varName), + ObjectIdGetDatum(varNamespace))) + { + } I am confused by these comments. i think the SearchSysCacheExists2 do actually prevent duplicates. I noticed that publication_add_relation also has similar comments. ----------------<<>>------------------------- typedef struct LetStmt { NodeTag type; List *target; /* target variable */ Node *query; /* source expression */ int location; } LetStmt; here, location should be a type of ParseLoc. ----------------<<>>------------------------- in 0001, 0002, function SetSessionVariableWithSecurityCheck never being used. ----------------<<>>------------------------- +/* + * transformLetStmt - + * transform an Let Statement + */ +static Query * +transformLetStmt(ParseState *pstate, LetStmt *stmt) ... + /* + * Save target session variable ID. This value is used multiple times: by + * the query rewriter (for getting related defexpr), by planner (for + * acquiring an AccessShareLock on target variable), and by the executor + * (we need to know the target variable ID). + */ + query->resultVariable = varid; "defexpr", do you mean "default expression"? Generally letsmt is like: "let variable = (SelectStmt)" is there nothing related to the DEFAULT expression? "(we need to know the target variable ID)." in ExecuteLetStmt that is true. but I commented out the following lines, the regress test still succeeded. extract_query_dependencies_walker /* record dependency on the target variable of a LET command */ // if (OidIsValid(query->resultVariable)) // record_plan_variable_dependency(context, query->resultVariable); ScanQueryForLocks // /* process session variables */ // if (OidIsValid(parsetree->resultVariable)) // { // if (acquire) // LockDatabaseObject(VariableRelationId, parsetree->resultVariable, // 0, AccessShareLock); // else // UnlockDatabaseObject(VariableRelationId, parsetree->resultVariable, // 0, AccessShareLock); // } ----------------<<>>------------------------- in transformLetStmt, we already did ACL privilege check, we don't need do it again at ExecuteLetStmt?
hi. src9=# select 'XLogRecPtr'::regtype; ERROR: type "xlogrecptr" does not exist LINE 1: select 'XLogRecPtr'::regtype; ^ so + <structfield>varcreate_lsn</structfield> <type>XLogRecPtr</type> should be <structfield>varcreate_lsn</structfield> <type>pg_lsn</type> ? also + <row> + <entry role="catalog_table_entry"><para role="column_definition"> + <structfield>varcreate_lsn</structfield> <type>XLogRecPtr</type> + </para> + <para> + LSN of the transaction where the variable was created. + <structfield>varcreate_lsn</structfield> and + <structfield>oid</structfield> together form the all-time unique + identifier (<structfield>oid</structfield> alone is not enough, since + object identifiers can get reused). + </para></entry> + </row> + we have "pg_variable_oid_index" PRIMARY KEY, btree (oid) for table pg_variable. so I am confused by saying the column "oid" itself is not enough to prove unique. in let.sgml <term><literal>session_variable</literal></term> should be <term><replaceable class="parameter">session_variable</replaceable></term> <term><literal>sql_expression</literal></term> should be <term><replaceable class="parameter">sql_expression</replaceable></term>
Hi
pá 27. 12. 2024 v 16:20 odesílatel jian he <jian.universality@gmail.com> napsal:
hi.
+ if (!OidIsValid(varid))
+ AcceptInvalidationMessages();
+ else if (OidIsValid(varid))
+ LockDatabaseObject(VariableRelationId, varid, 0, AccessShareLock);
we can change it to
+ if (!OidIsValid(varid))
+ AcceptInvalidationMessages();
+ else
+ LockDatabaseObject(VariableRelationId, varid, 0, AccessShareLock);
done
inval_count didn't explain at all, other places did actually explain it.
Can we add some text explaining inval_count? (i didn't fully understand
this part, that is why i am asking..)
done
seems IdentifyVariable all these three ereport(ERROR...) don't have
regress tests,
i think we should have it. Am I missing something?
done
create variable v2 as int;
let v2.a = 1;
ERROR: type "integer" of target session variable "public.v2" is not a
composite type
LINE 1: let v2.a = 1;
^
the error messages look weird.
IMO, it should either be
"type of session variable "public.v2" is not a composite type"
or
"session variable "public.v2" don't have attribute "a"
changed
I did inspiration from transformAssignmentIndirection now
(2024-12-28 16:07:57) postgres=# let x.a = 20;
ERROR: cannot assign to field "a" of session variable "public.x" because its type integer is not a composite type
LINE 1: let x.a = 20;
^
ERROR: cannot assign to field "a" of session variable "public.x" because its type integer is not a composite type
LINE 1: let x.a = 20;
^
also, the above can be as a regress test for:
+ if (attrname && !is_rowtype)
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("type \"%s\" of target session variable \"%s.%s\" is not a
composite type",
+ format_type_be(typid),
+ get_namespace_name(get_session_variable_namespace(varid)),
+ get_session_variable_name(varid)),
+ parser_errposition(pstate, stmt->location)));
since we don't have coverage tests for it.
done
+ if (coerced_expr == NULL)
+ ereport(ERROR,
+ (errcode(ERRCODE_DATATYPE_MISMATCH),
+ errmsg("variable \"%s.%s\" is of type %s,"
+ " but expression is of type %s",
+ get_namespace_name(get_session_variable_namespace(varid)),
+ get_session_variable_name(varid),
+ format_type_be(typid),
+ format_type_be(exprtypid)),
+ errhint("You will need to rewrite or cast the expression."),
+ parser_errposition(pstate, exprLocation((Node *) expr))));
generally, errmsg(...) should put it into one line for better grep-ability
so we can change it to:
+errmsg("variable \"%s.%s\" is of type %s, but expression is of type %s"...)
done
also no coverage tests?
simple test case for it:
create variable v2 as int;
let v2 = '1'::jsonb;
done
---------------<<<>>>--------------
+let_target:
+ ColId opt_indirection
+ {
+ $$ = list_make1(makeString($1));
+ if ($2)
+ $$ = list_concat($$,
+ check_indirection($2, yyscanner));
+ }
if you look closely, it seems the indentation level is wrong in
line "$$ = list_concat($$,"?
let_target is not needed as separate rule now, so I removed it and little bit cleaned (really only little bit)
---------------<<<>>>--------------
i did some refactoring in session_variables.sql for privilege check.
make the tests more neat, please check attached.
merged with minor changes in comment's formatting
I'll send the patch set with next mail
Best regards
Pavel
hi. + if (stmt->collClause) + collation = LookupCollation(pstate, + stmt->collClause->collname, + stmt->collClause->location); + else + collation = typcollation;; two semi-colon. should be only one. ------------------<<>>>--------------- + /* locks the variable with an AccessShareLock */ + varid = IdentifyVariable(names, &attrname, ¬_unique, false); + if (not_unique) + ereport(ERROR, + (errcode(ERRCODE_AMBIGUOUS_PARAMETER), + errmsg("target \"%s\" of LET command is ambiguous", + NameListToString(names)), + parser_errposition(pstate, stmt->location))); the following are tests for the above "LET command is ambiguous" error message. create schema test; CREATE TYPE test AS (test int); CREATE variable test.test as test; set search_path to test; let test.test = 1; ------------------<<>>>--------------- + else + { + /* the last field of list can be star too */ + Assert(IsA(field2, A_Star)); + + /* + * In this case, the field1 should be variable name. But + * direct unboxing of composite session variables is not + * supported now, and then we don't need to try lookup + * related variable. + * + * Unboxing is supported by syntax (var).* + */ + return InvalidOid; + } I don't fully understand the above comments, add `elog(INFO, "%s:%d called", __FILE__, __LINE__); ` within the ELSE branch. Then I found out the ELSE branch doesn't have coverage tests. ------------------<<>>>--------------- + /* + * a.b.c can mean catalog.schema.variable or + * schema.variable.field. .... + /* + * a.b can mean "schema"."variable" or "variable"."field". + * Check both variants, and returns InvalidOid with + * not_unique flag, when both interpretations are + * possible. + */ here, we use the word "field", but the function IdentifyVariable above comment, we use word "attribute", for consistency's sake, we should use "attribute" instead of "field" +/* ----- + * IdentifyVariable - try to find a variable from a list of identifiers + * + * Returns the OID of the variable found, or InvalidOid. + * + * "names" is a list of up to four identifiers; possible meanings are: + * - variable (searched on the search_path) + * - schema.variable + * - variable.attribute (searched on the search_path) + * - schema.variable.attribute + * - database.schema.variable + * - database.schema.variable.attribute ------------------<<>>>---------------
Hi
so 28. 12. 2024 v 11:35 odesílatel jian he <jian.universality@gmail.com> napsal:
hi.
src9=# select 'XLogRecPtr'::regtype;
ERROR: type "xlogrecptr" does not exist
LINE 1: select 'XLogRecPtr'::regtype;
^
so
+ <structfield>varcreate_lsn</structfield> <type>XLogRecPtr</type>
should be
<structfield>varcreate_lsn</structfield> <type>pg_lsn</type>
?
done
also
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>varcreate_lsn</structfield> <type>XLogRecPtr</type>
+ </para>
+ <para>
+ LSN of the transaction where the variable was created.
+ <structfield>varcreate_lsn</structfield> and
+ <structfield>oid</structfield> together form the all-time unique
+ identifier (<structfield>oid</structfield> alone is not enough, since
+ object identifiers can get reused).
+ </para></entry>
+ </row>
+
we have "pg_variable_oid_index" PRIMARY KEY, btree (oid)
for table pg_variable.
so I am confused by saying the column "oid" itself is not enough to
prove unique.
The session variable is stored in memory until the end of the session. Theoretically, some sessions with used session variables can be opened for a very long time without any activity - so it is not possible to process sinval message. Other sessions can drop and create a lot of session variables (this is very possible with temporary session variables). Oid in Postgres can overflow, and postgres can reuse used oid of dropped objects (oid is only 32bit integer). And after some time, the session with the used variable can be activated, and the session variable can be used. Before usage the session variable is rechecked against pg_variable, and theoretically the variable with the same oid can be there (although it is a different variable with possibly different type). The implementation should protect against this scenario. The stored value must not be used in this case - the usage of old value is dangerous - the calculations with the variable can lose sense or can crash postgres. LSN is forever unique - it is 64bit integer - so it is our safeguard so we can detect obsolete values (stored in memory) although there are variables with the same oid.
oid in pg_variable ensures a unique identifier for any session variable in one moment. Compound key [oid, varcreate_lsn] is a unique identifier for ever.
in let.sgml
<term><literal>session_variable</literal></term>
should be
<term><replaceable class="parameter">session_variable</replaceable></term>
done
<term><literal>sql_expression</literal></term>
should be
<term><replaceable class="parameter">sql_expression</replaceable></term>
done
On Sun, Dec 29, 2024 at 5:50 AM Pavel Stehule <pavel.stehule@gmail.com> wrote: > > Hi > > >> ------------------<<>>>--------------- >> + else >> + { >> + /* the last field of list can be star too */ >> + Assert(IsA(field2, A_Star)); >> + >> + /* >> + * In this case, the field1 should be variable name. But >> + * direct unboxing of composite session variables is not >> + * supported now, and then we don't need to try lookup >> + * related variable. >> + * >> + * Unboxing is supported by syntax (var).* >> + */ >> + return InvalidOid; >> + } >> I don't fully understand the above comments, > > > The parser allows only two syntaxes - identifier.identifier or identifier.star. Second > syntax is not supported by session variables, and then I didn't try to search for the variable. > Some users can be confused by similar syntaxes identifier.* and (identifier).* Only > second syntax is composite unboxing, and only second syntax is supported for > session variables. > > Maybe the note about unboxing is messy there? > >> add >> `elog(INFO, "%s:%d called", __FILE__, __LINE__); ` within the ELSE branch. >> Then I found out the ELSE branch doesn't have coverage tests. > > > I don't understand this comment? I don't use elog(INFO anywhere > > sorry for confusion, i mean, i added " elog(INFO", the regress test is still successful, therefore it means the above ELSE branch code doesn't have coverage tests.
Hi
+ {
+ /* the last field of list can be star too */
+ Assert(IsA(field2, A_Star));
+
+ /*
+ * In this case, the field1 should be variable name. But
+ * direct unboxing of composite session variables is not
+ * supported now, and then we don't need to try lookup
+ * related variable.
+ *
+ * Unboxing is supported by syntax (var).*
+ */
+ return InvalidOid;
+ }
I don't fully understand the above comments,The parser allows only two syntaxes - identifier.identifier or identifier.star. Secondsyntax is not supported by session variables, and then I didn't try to search for the variable.Some users can be confused by similar syntaxes identifier.* and (identifier).* Onlysecond syntax is composite unboxing, and only second syntax is supported forsession variables.
I changed this comment to
<--><--><--><--><-->/*
<--><--><--><--><--> * The syntax ident.* is used only by table aliases,
<--><--><--><--><--> * and then this identifier cannot be a reference to
<--><--><--><--><--> * session variable.
<--><--><--><--><--> */
<--><--><--><--><--> * The syntax ident.* is used only by table aliases,
<--><--><--><--><--> * and then this identifier cannot be a reference to
<--><--><--><--><--> * session variable.
<--><--><--><--><--> */
diff --git a/src/include/nodes/primnodes.h b/src/include/nodes/primnodes.h index 9c2957eb546..624858db301 100644 --- a/src/include/nodes/primnodes.h +++ b/src/include/nodes/primnodes.h @@ -361,6 +361,9 @@ typedef struct Const * of the `paramid' field contain the SubLink's subLinkId, and * the low-order 16 bits contain the column number. (This type * of Param is also converted to PARAM_EXEC during planning.) + * + * PARAM_VARIABLE: The parameter is a reference to a session variable + * (paramid holds the variable's OID). */ typedef enum ParamKind { @@ -368,6 +371,7 @@ typedef enum ParamKind PARAM_EXEC, PARAM_SUBLINK, PARAM_MULTIEXPR, + PARAM_VARIABLE, } ParamKind; typedef struct Param @@ -380,6 +384,10 @@ typedef struct Param int32 paramtypmod pg_node_attr(query_jumble_ignore); /* OID of collation, or InvalidOid if none */ Oid paramcollid pg_node_attr(query_jumble_ignore); + /* OID of session variable if it is used */ + Oid paramvarid; + /* true when param is used like base node of assignment indirection */ + bool parambasenode; /* token location, or -1 if unknown */ ParseLoc location; } Param; comment should be "(paramvarid holds the variable's OID)" also + /* true when param is used like base node of assignment indirection */ is kind of hard to understand. param->parambasenode = true; only happens in transformLetStmt so we can change it to + /* true when param is used in part of the LET statement.*/ --- a/src/include/executor/execdesc.h +++ b/src/include/executor/execdesc.h @@ -51,6 +51,10 @@ typedef struct QueryDesc /* This field is set by ExecutePlan */ bool already_executed; /* true if previously executed */ + /* reference to session variables buffer */ + int num_session_variables; + SessionVariableValue *session_variables; + /* This is always set NULL by the core system, but plugins can change it */ struct Instrumentation *totaltime; /* total time spent in ExecutorRun */ } QueryDesc; QueryDesc->num_session_variables and QueryDesc->session_variables are never used in 0001 and 0002. it may be used in later patches, but at least 0001 and 0002, we don't need to change struct QueryDesc? contrib/postgres_fdw/deparse.c There are some cases of "case T_Param:" do we need to do something on it? also on src/backend/nodes/queryjumblefuncs.c, one appearance of "case T_Param:". (but it seems no need change here) CREATE VARIABLE v1 AS int; CREATE VARIABLE v2 AS int; SELECT pg_stat_statements_reset() IS NOT NULL AS t; select count(*) from tenk1 where unique1 = v1; select count(*) from tenk1 where unique1 = v2; should the last two queries be normalized as one query in pg_stat_statements? if so, then maybe in typedef struct Param we need change to: Oid paramvarid pg_node_attr(query_jumble_ignore); but then let v1 = v1+1; let v1 = v2+1; will be normalized as one query.
+ /* + * The arguments of EXECUTE are evaluated by a direct expression + * executor call. This mode doesn't support session variables yet. + * It will be enabled later. + */ + if (pstate->p_hasSessionVariables) + elog(ERROR, "session variable cannot be used as an argument"); it should be: /* * The arguments of CALL statement are evaluated by a direct expression * executor call. This path is unsupported yet, so block it. */ if (pstate->p_hasSessionVariables) ereport(ERROR, errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("session variable cannot be used as an argument")); similarly, EvaluateParams we can change it to /* * The arguments of EXECUTE are evaluated by a direct expression * executor call. This mode doesn't support session variables yet. * It will be enabled later. */ if (pstate->p_hasSessionVariables) ereport(ERROR, errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("session variable cannot be used as an argument")); in src/backend/executor/execExpr.c we don't need +#include "catalog/pg_variable.h" ?
Hi
ne 5. 1. 2025 v 5:52 odesílatel jian he <jian.universality@gmail.com> napsal:
diff --git a/src/include/nodes/primnodes.h b/src/include/nodes/primnodes.h
index 9c2957eb546..624858db301 100644
--- a/src/include/nodes/primnodes.h
+++ b/src/include/nodes/primnodes.h
@@ -361,6 +361,9 @@ typedef struct Const
* of the `paramid' field contain the SubLink's subLinkId, and
* the low-order 16 bits contain the column number. (This type
* of Param is also converted to PARAM_EXEC during planning.)
+ *
+ * PARAM_VARIABLE: The parameter is a reference to a session variable
+ * (paramid holds the variable's OID).
*/
typedef enum ParamKind
{
@@ -368,6 +371,7 @@ typedef enum ParamKind
PARAM_EXEC,
PARAM_SUBLINK,
PARAM_MULTIEXPR,
+ PARAM_VARIABLE,
} ParamKind;
typedef struct Param
@@ -380,6 +384,10 @@ typedef struct Param
int32 paramtypmod pg_node_attr(query_jumble_ignore);
/* OID of collation, or InvalidOid if none */
Oid paramcollid pg_node_attr(query_jumble_ignore);
+ /* OID of session variable if it is used */
+ Oid paramvarid;
+ /* true when param is used like base node of assignment indirection */
+ bool parambasenode;
/* token location, or -1 if unknown */
ParseLoc location;
} Param;
comment should be "(paramvarid holds the variable's OID)"
also
+ /* true when param is used like base node of assignment indirection */
is kind of hard to understand.
param->parambasenode = true;
only happens in transformLetStmt so we can change it to
+ /* true when param is used in part of the LET statement.*/
I don't think the proposed change of comment is better, but the text
can be extended.
<-->/*
<--> * true if param is used as base node of assignment indirection
<--> * (when target of LET statement is an array field or an record field).
<--> * For this param we do not check SELECT access right, because this
<--> * param is used just for execution of UPDATE operation.
<--> */
<--> * true if param is used as base node of assignment indirection
<--> * (when target of LET statement is an array field or an record field).
<--> * For this param we do not check SELECT access right, because this
<--> * param is used just for execution of UPDATE operation.
<--> */
--- a/src/include/executor/execdesc.h
+++ b/src/include/executor/execdesc.h
@@ -51,6 +51,10 @@ typedef struct QueryDesc
/* This field is set by ExecutePlan */
bool already_executed; /* true if previously executed */
+ /* reference to session variables buffer */
+ int num_session_variables;
+ SessionVariableValue *session_variables;
+
/* This is always set NULL by the core system, but plugins can change it */
struct Instrumentation *totaltime; /* total time spent in ExecutorRun */
} QueryDesc;
QueryDesc->num_session_variables and
QueryDesc->session_variables are never used in 0001 and 0002.
it may be used in later patches,
but at least 0001 and 0002, we don't need to change
struct QueryDesc?
moved to patch 17
contrib/postgres_fdw/deparse.c
There are some cases of "case T_Param:"
do we need to do something on it?
I think so session variables cannot be executed remotely, and then do nothing there it is correct.
also on src/backend/nodes/queryjumblefuncs.c, one
appearance of "case T_Param:". (but it seems no need change here)
CREATE VARIABLE v1 AS int;
CREATE VARIABLE v2 AS int;
SELECT pg_stat_statements_reset() IS NOT NULL AS t;
select count(*) from tenk1 where unique1 = v1;
select count(*) from tenk1 where unique1 = v2;
should the last two queries be normalized as one query in pg_stat_statements?
if so, then maybe in typedef struct Param
we need change to:
Oid paramvarid pg_node_attr(query_jumble_ignore);
changed
In this case for this moment we can try to be consistent with plpgsql variables. So I did it
but then
let v1 = v1+1;
let v1 = v2+1;
will be normalized as one query.
yes, but this case is not too important, because at the end (I hope), this statement inside plpgsql will be executed as
simple expression, and then it will not be processed by pg_stat_statements
ne 5. 1. 2025 v 17:11 odesílatel jian he <jian.universality@gmail.com> napsal:
+ /*
+ * The arguments of EXECUTE are evaluated by a direct expression
+ * executor call. This mode doesn't support session variables yet.
+ * It will be enabled later.
+ */
+ if (pstate->p_hasSessionVariables)
+ elog(ERROR, "session variable cannot be used as an argument");
it should be:
/*
* The arguments of CALL statement are evaluated by a direct expression
* executor call. This path is unsupported yet, so block it.
*/
if (pstate->p_hasSessionVariables)
ereport(ERROR,
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("session variable cannot be used as an argument"));
done
similarly, EvaluateParams we can change it to
/*
* The arguments of EXECUTE are evaluated by a direct expression
* executor call. This mode doesn't support session variables yet.
* It will be enabled later.
*/
if (pstate->p_hasSessionVariables)
ereport(ERROR,
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("session variable cannot be used as an argument"));
done
in src/backend/executor/execExpr.c
we don't need
+#include "catalog/pg_variable.h"
?
moved to patch 16
hi. some minor issues. 'transformMergeStmt also needs "qry->hasSessionVariables = pstate->p_hasSessionVariables;" ? <function>acldefault</function> in doc/src/sgml/func.sgml Need an update for SESSION VARIABLE? Table 9.70. Access Privilege Inquiry Functions sorting order: has_session_variable_privilege should after has_server_privilege? Similar to src/test/regress/sql/event_trigger.sql, we can use the following query to test four functions in Table 9.79. Object Information and Addressing Functions (9.27.5. Object Information and Addressing Functions) for session variables. SELECT e.varname, pg_describe_object('pg_variable'::regclass, e.oid, 0) as descr, b.type, b.object_names, b.object_args, pg_identify_object(a.classid, a.objid, a.objsubid) as ident FROM pg_variable as e, LATERAL pg_identify_object_as_address('pg_variable'::regclass, e.oid, 0) as b, LATERAL pg_get_object_address(b.type, b.object_names, b.object_args) as a; in function transformColumnRef if (expr_kind_allows_session_variables(pstate->p_expr_kind)) { } can change to if (!node && !(relname && crerr == CRERR_NO_COLUMN) && expr_kind_allows_session_variables(pstate->p_expr_kind)) { } can reduce the function call of expr_kind_allows_session_variables, also not lose readability. typedef struct SVariableData says: /* * Stored value and type description can be outdated when we receive a * sinval message. We then have to check if the stored data are still * trustworthy. */ bool is_valid; CREATE VARIABLE var3 AS int; LET var3 = 10; GRANT SELECT ON VARIABLE var3 TO regress_noowner; I don't understand why the last statement GRANT SELECT needs to call pg_variable_cache_callback? and it will invalidate the original var3. +/* + * Returns a copy of the value of the session variable (in the current memory + * context). The caller is responsible for permission checks. + */ +Datum +GetSessionVariable(Oid varid, bool *isNull, Oid *typid) +{ + SVariable svar; + + svar = get_session_variable(varid); + + /* + * Although "svar" is freshly validated in this point, svar->is_valid can + * be false, if an invalidation message ws processed during the domain check. + * But the variable and all its dependencies are locked now, so we don't need + * to repeat the validation. + */ + Assert(svar); + + *typid = svar->typid; + + return copy_session_variable_value(svar, isNull); +} typo, "ws processed" should be "was processed". also the Assert is not helpful? since svar is NULL, get_session_variable would have segfault. also SVariable svar; is not initialized to NULL, so generally it will not be NULL by default. also the comments seem to imply that before copy_session_variable_value, svar->is_valid can be false. if svar->is_valid is false, then why do copy_session_variable_value.
hi. you forgot change <function>acldefault</function> should add 'V' for <literal>SESSION VARIABLE</literal> in doc/src/sgml/ddl.sgml <sect1 id="ddl-session-variables"> maybe some examples (<programlisting>) of session variables being shadowed would be great. because doc/src/sgml/ref/create_variable.sgml said <note> <para> Session variables can be <quote>shadowed</quote> by other identifiers. For details, see <xref linkend="ddl-session-variables"/>. </para> </note> If I click the link, then in ddl.sgml, there is also a bunch of text saying that variable will be shadowed in some situations, but there are no simple examples to demonstrate that. "Create an date session variable <literal>var1</literal>:" maybe it should be rephrased as "Create a session variable <literal>var1</literal> as date data type?" (i am not native english speaker) ----------------------------------------------------------------------- --- a/src/include/nodes/primnodes.h +++ b/src/include/nodes/primnodes.h @@ -379,7 +379,8 @@ typedef struct Param Expr xpr; ParamKind paramkind; /* kind of parameter. See above */ int paramid; /* numeric ID for parameter */ - Oid paramtype; /* pg_type OID of parameter's datatype */ + /* pg_type OID of parameter's datatype */ + Oid paramtype pg_node_attr(query_jumble_ignore); I think we need the above to make select v2; select v1; normalized as one query. ----------------------------------------------------------------------- when we create a new table, we do something like this: DefineRelation heap_create_with_catalog GetNewRelFileNumber GetNewOidWithIndex relation Oid uniqueness and variable uniqueness is the same thing. If variable oid uniqueness problem ever reached, at that moment, we should care more about relation oid uniqueness problem? and in GetNewRelFileNumber, we have comments: "" * As with GetNewOidWithIndex(), there is some theoretical risk of a race * condition, but it doesn't seem worth worrying about. """ also comments in GetNewOidWithIndex """ * Note that we are effectively assuming that the table has a relatively small * number of entries (much less than 2^32) and there aren't very long runs of * consecutive existing OIDs. This is a mostly reasonable assumption for * system catalogs. """ that means pg_catalog.pg_variable.varcreate_lsn is not really necessary? ----------------------------------------------------------------------- I think the latest patch for LET self assign ACL SELECT is not correct, previously I also tried the same idea. test demo. CREATE TYPE vartest_t1 AS (a int, b int); CREATE VARIABLE var1 AS vartest_t1; CREATE ROLE regress_var_test_role; GRANT UPDATE ON VARIABLE var1 TO regress_var_test_role; GRANT select ON table tenk1 TO regress_var_test_role; SET ROLE TO regress_var_test_role; --both should fail LET var1.a = var1.a + 10; LET var1.a = (select * from (select count(*) from tenk1 where unique1 = var1.a + 10)); --------------------------------------------------------
On Fri, Jan 17, 2025 at 08:18:20AM +0100, Pavel Stehule wrote: > Hi > > fix oid collision What is the purpose of continually posting this patch to the email lists? -- Bruce Momjian <bruce@momjian.us> https://momjian.us EDB https://enterprisedb.com Do not let urgent matters crowd out time for investment in the future.
Hi
pá 17. 1. 2025 v 14:41 odesílatel Bruce Momjian <bruce@momjian.us> napsal:
On Fri, Jan 17, 2025 at 08:18:20AM +0100, Pavel Stehule wrote:
> Hi
>
> fix oid collision
What is the purpose of continually posting this patch to the email
lists?
The people still do a review, so I am fixing this patch. I am fixing it immediately, when I detect an issue.
I can reduce the frequency once per week.
Regards
Pavel
--
Bruce Momjian <bruce@momjian.us> https://momjian.us
EDB https://enterprisedb.com
Do not let urgent matters crowd out time for investment in the future.
On Fri, Jan 17, 2025 at 02:48:29PM +0100, Pavel Stehule wrote: > Hi > > pá 17. 1. 2025 v 14:41 odesílatel Bruce Momjian <bruce@momjian.us> napsal: > > On Fri, Jan 17, 2025 at 08:18:20AM +0100, Pavel Stehule wrote: > > Hi > > > > fix oid collision > > What is the purpose of continually posting this patch to the email > lists? > > > The people still do a review, so I am fixing this patch. I am fixing it > immediately, when I detect an issue. > > I can reduce the frequency once per week. Is this really something we are considering applying, since it has been around for years? I am unclear on that and we had better know if we are going to continue reviewing this. -- Bruce Momjian <bruce@momjian.us> https://momjian.us EDB https://enterprisedb.com Do not let urgent matters crowd out time for investment in the future.
On 2025-Jan-17, Bruce Momjian wrote: > Is this really something we are considering applying, since it has been > around for years? I am unclear on that and we had better know if we are > going to continue reviewing this. The fact that the patch has been around for years doesn't automatically mean it's a bad idea. I have proposed that we discuss this patch at fosdem developer's meeting next month, precisely to seek consensus on whether this patch is something we want or not. My view is that this is a feature that has been requested by users for years, so IMO we want this or something similar. I wonder if the reason that committers stay away from it is that reviewing it fully (and thus taking responsibility for it) seems such a daunting task. I might be wrong, but I think this may be the largest patch since FTS. -- Álvaro Herrera 48°01'N 7°57'E — https://www.EnterpriseDB.com/ Tom: There seems to be something broken here. Teodor: I'm in sackcloth and ashes... Fixed. http://postgr.es/m/482D1632.8010507@sigaev.ru
Hi
pá 17. 1. 2025 v 15:39 odesílatel Bruce Momjian <bruce@momjian.us> napsal:
On Fri, Jan 17, 2025 at 03:28:55PM +0100, Pavel Stehule wrote:
> Dne pá 17. 1. 2025 15:16 uživatel Bruce Momjian <bruce@momjian.us> napsal:
> Is this really something we are considering applying, since it has been
> around for years? I am unclear on that and we had better know if we are
> going to continue reviewing this.
>
> I hope so it is possible, minimally in some basic form. And i think so there
> was real good progres of quality in last three months.
I am not asking if it is improving. I am asking if it is a desired
feature; see:
https://wiki.postgresql.org/wiki/Todo#Development_Process
Desirability -> Design -> Implement -> Test -> Review -> Commit
I am asking if we have had the Desirability discussion, and its outcome,
because if we can't agree on its Desirability, the other stages are
useless.
This discussion was around 2017 when I wrote a proposal and I hadn't a feeling so we don't write this feature.
Big discussion was related to whether variables should be transactional or not. Next the patch was stalled from
two reasons: a) there was not necessary infrastructure for utility commands, b) I searched for ways to ensure
the validity of the content of variables. I found a good solution at the end of 2022. It is true, so time has changed
from this time, and Postgres and people are different. In this time the migration from Oracle was stronger
topic.
If you read all the discussion, you can find more times the sentence so this can be a good feature (not from me).
Surely the session variables can be implemented differently - minimally there are four different implementations
mssql, db2, mysql and oracle, and there can be unfinished discussion about which way is better or if the session
variables are necessary. Yes, we can live without it - we are living without it, but emulation by GUC is not secure,
so some scenarios are not possible, and others are breakneck with emulation.
I understand the question if we need it is open still and every time. This feature is interesting for people who
a) use stored procedures
b) use RLS
Both these groups are not the majority of users. But these people are here.
Btw - EDB supports Oracle way, and Postgres Pro uses extension for emulation. So there is a real request
for this feature. Common solution for Postgres is using GUC. But there is no possibility to set access
rights so the workaround cannot be secured.
There is one stronger argument for session variables - we are missing global temporary tables. It is a real
limit and more times I found users with bloated pg_class, pg_attributes due using temp tables. I don't believe
so we can have a global temp table - it is a significantly more difficult task than session variables. At the end
session variables are trivial against global temp tables, and can replace global temp tables in some use cases.
And the solution can be nicer, cleaner, safer than with a workaround based on GUC.
Regards
Pavel
--
Bruce Momjian <bruce@momjian.us> https://momjian.us
EDB https://enterprisedb.com
Do not let urgent matters crowd out time for investment in the future.
On Fri, Jan 17, 2025 at 04:32:07PM +0100, Pavel Stehule wrote: > This discussion was around 2017 when I wrote a proposal and I hadn't a feeling 2017 is seven years ago so it would be good to get current feedback on the desirability of this feature. > There is one stronger argument for session variables - we are missing global > temporary tables. It is a real > limit and more times I found users with bloated pg_class, pg_attributes due > using temp tables. I don't believe > so we can have a global temp table - it is a significantly more difficult task > than session variables. At the end > session variables are trivial against global temp tables, and can replace > global temp tables in some use cases. > And the solution can be nicer, cleaner, safer than with a workaround based on > GUC. So this feature would be like global GUC variables, with permission control? -- Bruce Momjian <bruce@momjian.us> https://momjian.us EDB https://enterprisedb.com Do not let urgent matters crowd out time for investment in the future.
pá 17. 1. 2025 v 16:35 odesílatel Bruce Momjian <bruce@momjian.us> napsal:
On Fri, Jan 17, 2025 at 04:32:07PM +0100, Pavel Stehule wrote:
> This discussion was around 2017 when I wrote a proposal and I hadn't a feeling
2017 is seven years ago so it would be good to get current feedback on
the desirability of this feature.
> There is one stronger argument for session variables - we are missing global
> temporary tables. It is a real
> limit and more times I found users with bloated pg_class, pg_attributes due
> using temp tables. I don't believe
> so we can have a global temp table - it is a significantly more difficult task
> than session variables. At the end
> session variables are trivial against global temp tables, and can replace
> global temp tables in some use cases.
> And the solution can be nicer, cleaner, safer than with a workaround based on
> GUC.
So this feature would be like global GUC variables, with permission
control?
+ it is declared - so less space for misuse is there. Custom GUC are absolutely tolerant
+ it is a fully database object, only owner can alter it, and event triggers are supported, sinval
+ possibility to set mutability, default value
Regards
Pavel
--
Bruce Momjian <bruce@momjian.us> https://momjian.us
EDB https://enterprisedb.com
Do not let urgent matters crowd out time for investment in the future.
On Fri, Jan 17, 2025 at 04:55:07PM +0100, Pavel Stehule wrote: > pá 17. 1. 2025 v 16:35 odesílatel Bruce Momjian <bruce@momjian.us> napsal: > > So this feature would be like global GUC variables, with permission > control? > > + types and domain type check - holds data in binary form - there are not > conversions binary, text > + it is declared - so less space for misuse is there. Custom GUC are absolutely > tolerant > + it is a fully database object, only owner can alter it, and event triggers > are supported, sinval > + possibility to set mutability, default value Okay, good summary. Now, can people give feedback that they would want this committed to PostgreSQL? -- Bruce Momjian <bruce@momjian.us> https://momjian.us EDB https://enterprisedb.com Do not let urgent matters crowd out time for investment in the future.
On Fri, Jan 17, 2025 at 11:01:41AM -0500, Bruce Momjian wrote: > On Fri, Jan 17, 2025 at 04:55:07PM +0100, Pavel Stehule wrote: > > pá 17. 1. 2025 v 16:35 odesílatel Bruce Momjian <bruce@momjian.us> napsal: > > > > So this feature would be like global GUC variables, with permission > > control? > > > > + types and domain type check - holds data in binary form - there are not > > conversions binary, text > > + it is declared - so less space for misuse is there. Custom GUC are absolutely > > tolerant > > + it is a fully database object, only owner can alter it, and event triggers > > are supported, sinval > > + possibility to set mutability, default value > > Okay, good summary. Now, can people give feedback that they would want > this committed to PostgreSQL? I unsurprisingly would really like to see it committed, for all the reasons Pavel mentioned. It would have helped me on various projects many times.
On Fri, 2025-01-17 at 11:01 -0500, Bruce Momjian wrote: > On Fri, Jan 17, 2025 at 04:55:07PM +0100, Pavel Stehule wrote: > > pá 17. 1. 2025 v 16:35 odesílatel Bruce Momjian <bruce@momjian.us> napsal: > > > > So this feature would be like global GUC variables, with permission > > control? > > > > + types and domain type check - holds data in binary form - there are not > > conversions binary, text > > + it is declared - so less space for misuse is there. Custom GUC are absolutely > > tolerant > > + it is a fully database object, only owner can alter it, and event triggers > > are supported, sinval > > + possibility to set mutability, default value > > Okay, good summary. Now, can people give feedback that they would want > this committed to PostgreSQL? I would like to see this committed too, or at least relevant parts of it. It addresses the perennial problem of people putting state into placeholder GUCs to pass information between the application and the database (SET myapp.application_id = 'user_laurenz'). Also, it cann pass information between the code in DO statements and the surrounding SQL code. Yours, Laurenz Albe
> On Fri, Jan 17, 2025 at 11:01:41AM GMT, Bruce Momjian wrote: > On Fri, Jan 17, 2025 at 04:55:07PM +0100, Pavel Stehule wrote: > > pá 17. 1. 2025 v 16:35 odesílatel Bruce Momjian <bruce@momjian.us> napsal: > > > > So this feature would be like global GUC variables, with permission > > control? > > > > + types and domain type check - holds data in binary form - there are not > > conversions binary, text > > + it is declared - so less space for misuse is there. Custom GUC are absolutely > > tolerant > > + it is a fully database object, only owner can alter it, and event triggers > > are supported, sinval > > + possibility to set mutability, default value > > Okay, good summary. Now, can people give feedback that they would want > this committed to PostgreSQL? +1 into the bucket "want committed" from me as well. Throughout the review process I've stumbled upon a few cases in my own projects, where it would be useful.
Bruce Momjian: > Now, can people give feedback that they would want > this committed to PostgreSQL? From a user's perspective: Yes! I've been waiting for this for a long time and I really hope this can go through, eventually. Best, Wolfgang
> pá 17. 1. 2025 v 16:35 odesílatel Bruce Momjian <bruce@momjian.us> napsal:
Okay, good summary. Now, can people give feedback that they would want
this committed to PostgreSQL?
I would love to have this functionality as soon as possible.
I already mentioned to Pavel that he did something very big, and consequently difficult for anyone to commit, because these patches change a lot of things in a lot of places.
Of course we want as much as possible, but who knows if a first, leaner version was committed, with just session variables, so nothing related to schemas, catalogs, grants, dumps, etc, just a variable in memory, only that. It would be really cool, and certainly easier for a committer to agree with the code. And if the first commit occurs, others can follow.
Of course we want as much as possible, but who knows if a first, leaner version was committed, with just session variables, so nothing related to schemas, catalogs, grants, dumps, etc, just a variable in memory, only that. It would be really cool, and certainly easier for a committer to agree with the code. And if the first commit occurs, others can follow.
Remember that some people don't use PSQL, so they don't have \set
Even \set variables are not typed, so CREATE VARIABLE T AS DOMAIN_NUMBER_BETWEEN_1_AND_5 is really cool.
regards
Marcos
Em sex., 17 de jan. de 2025 às 13:01, Bruce Momjian <bruce@momjian.us> escreveu:
Okay, good summary. Now, can people give feedback that they would want
this committed to PostgreSQL?
I would love to have this functionality as soon as possible.
I already mentioned to Pavel that he did something very big, and consequently difficult for anyone to commit, because these patches change a lot of things in a lot of places.
Of course we want as much as possible, but who knows if a first, leaner version was committed, with just session variables, so nothing related to schemas, catalogs, grants, dumps, etc, just a variable in memory, only that. It would be really cool, and certainly easier for a committer to agree with the code. And if the first commit occurs, others can follow.
Of course we want as much as possible, but who knows if a first, leaner version was committed, with just session variables, so nothing related to schemas, catalogs, grants, dumps, etc, just a variable in memory, only that. It would be really cool, and certainly easier for a committer to agree with the code. And if the first commit occurs, others can follow.
Remember that some people don't use PSQL, so they don't have \set
Even \set variables are not typed, so CREATE VARIABLE T AS DOMAIN_NUMBER_BETWEEN_1_AND_5 is really cool.
regards
Marcos
Le 17/01/2025 à 19:01, Bruce Momjian a écrit : > On Fri, Jan 17, 2025 at 04:55:07PM +0100, Pavel Stehule wrote: >> pá 17. 1. 2025 v 16:35 odesílatel Bruce Momjian <bruce@momjian.us> napsal: >> >> So this feature would be like global GUC variables, with permission >> control? >> >> + types and domain type check - holds data in binary form - there are not >> conversions binary, text >> + it is declared - so less space for misuse is there. Custom GUC are absolutely >> tolerant >> + it is a fully database object, only owner can alter it, and event triggers >> are supported, sinval >> + possibility to set mutability, default value > Okay, good summary. Now, can people give feedback that they would want > this committed to PostgreSQL? > For me, this is a must have. Not only because of the huge amount of time that we will save in migration to PostgreSQL (i know that this is not an argument) but because the only way we have to emulate such feature is to use custom configuration directives or a PL language that allows global variable. I have question almost every week on how to do that and the only answer I have is do this ugly pl/pgsql coding. It will be nice to have a feature to do that. Thanks Pavel and all involved in this implementation. -- Gilles Darold http://www.darold.net/
Hi
po 20. 1. 2025 v 8:56 odesílatel Álvaro Herrera <alvherre@alvh.no-ip.org> napsal:
On 2025-Jan-17, Bruce Momjian wrote:
> Is this really something we are considering applying, since it has been
> around for years? I am unclear on that and we had better know if we are
> going to continue reviewing this.
The fact that the patch has been around for years doesn't automatically
mean it's a bad idea.
I have proposed that we discuss this patch at fosdem developer's meeting
next month, precisely to seek consensus on whether this patch is
something we want or not. My view is that this is a feature that has
been requested by users for years, so IMO we want this or something
similar.
I wonder if the reason that committers stay away from it is that
reviewing it fully (and thus taking responsibility for it) seems such a
daunting task. I might be wrong, but I think this may be the largest
patch since FTS.
This patch is huge, but I think it is not comparable with parallel processing support or with replication support.
It doesn't introduce new processes or new data structures or does important changes in planner, and I think so almost all code is very simple.
In early versions of this patch, there was a complex part to ensure validity of content in memory. But it was fully removed and replaced
just by comparing with create_lsn.
Regards
Pavel
--
Álvaro Herrera 48°01'N 7°57'E — https://www.EnterpriseDB.com/
Tom: There seems to be something broken here.
Teodor: I'm in sackcloth and ashes... Fixed.
http://postgr.es/m/482D1632.8010507@sigaev.ru
On Fri, Jan 17, 2025 at 03:47:28PM +0100, Álvaro Herrera wrote: > On 2025-Jan-17, Bruce Momjian wrote: > > > Is this really something we are considering applying, since it has been > > around for years? I am unclear on that and we had better know if we are > > going to continue reviewing this. > > The fact that the patch has been around for years doesn't automatically > mean it's a bad idea. Yes, I think we passed the Desirability criteria with the feedback on this thread, but it is now a question of whether the code complexity justifies the feature. I saw a few people saying they want _some_ parts of the patch, which opens the suggestion that even people who want the patch are seeing parts of the patch that are too much. I have seen this patch circling around, and I think it needs a step a back for analysis. > I have proposed that we discuss this patch at fosdem developer's meeting > next month, precisely to seek consensus on whether this patch is > something we want or not. My view is that this is a feature that has > been requested by users for years, so IMO we want this or something > similar. Yes, the meeting review is a very good idea. > I wonder if the reason that committers stay away from it is that > reviewing it fully (and thus taking responsibility for it) seems such a > daunting task. I might be wrong, but I think this may be the largest > patch since FTS. I think we have to identify a committer who is willing to consider application of this patch before the patch can move forward. -- Bruce Momjian <bruce@momjian.us> https://momjian.us EDB https://enterprisedb.com Do not let urgent matters crowd out time for investment in the future.
On Mon, 2025-01-20 at 15:15 -0500, Bruce Momjian wrote: > Yes, I think we passed the Desirability criteria with the feedback on > this thread, but it is now a question of whether the code complexity > justifies the feature. I saw a few people saying they want _some_ parts > of the patch, which opens the suggestion that even people who want the > patch are seeing parts of the patch that are too much. I have seen this > patch circling around, and I think it needs a step a back for analysis. I'd say that patches 1 to 6 from the patch set are essential. Yours, Laurenz Albe
hi. git diff --check shows there is some white space there. Adding hack mailing list discussion links in each patch would be great. Others said that the first 6 patches are essential, maybe we can only post the first 6 patches. so the test CI result would be more reliable. also people would not feel intimidated by the bigger patchset. create domain dnn as int not null; CREATE VARIABLE var3 AS dnn; alter domain dnn drop not null; alter domain dnn set not null; ERROR: cannot alter domain "dnn" because session variable "public.var3" uses it This is not great. we allow a constraint, then we drop it, now we cannot re add it again. 0001 and 0002 are simple, but the size is still large. maybe we can not support the domain in the first 2 patches. also CREATE VARIABLE var3 AS dnn; let var3 = 11; create view v1 as select var3; select * from v1; you can see reconnect to session then ERROR: domain dnn does not allow null values this is not ok? also create table t(var3 int); CREATE POLICY p1r ON t AS RESTRICTIVE TO alice USING (var3 <> var3); create table t1(a int); CREATE POLICY p2 ON t1 AS RESTRICTIVE TO alice USING (a <> var3); p1r is so confusing. there is no way to understand the intention. p2 should also not be allowed, since var3 value is volatile, session reconnection will change the value. src/bin/pg_dump/pg_dump.h /* * The VariableInfo struct is used to represent session variables */ typedef struct _VariableInfo { DumpableObject dobj; DumpableAcl dacl; Oid vartype; char *vartypname; char *varacl; char *rvaracl; char *initvaracl; char *initrvaracl; Oid varcollation; const char *rolname; /* name of owner, or empty string */ } VariableInfo; these fields (varacl, rvaracl, initvaracl, initrvaracl) were never being used. we can remove them. CollInfo *coll; coll = findCollationByOid(varcollation); if (coll) appendPQExpBuffer(query, " COLLATE %s", fmtQualifiedDumpable(coll)); here, it should be ```CollInfo *coll = NULL;```? I don't understand the changes made in getAdditionalACLs. I thought pg_init_privs had nothing to do with the session variable. minor issue in getVariables. query = createPQExpBuffer(); resetPQExpBuffer(query); no need to use resetPQExpBuffer here. create type ab as (a int, b text); create type abc as (a ab, c text); create type abcd as (a abc, d text); CREATE VARIABLE var2 AS abcd; select var2.a.c; ERROR: cross-database references are not implemented: var2.a.c Is this error what we expected? I am not 100% sure. --------------------another contrived corner case.----------------------- create type pg_variable as ( oid oid, vartype oid, varcreate_lsn pg_lsn, varname name, varnamespace oid, varowner oid, vartypmod int, varcollation oid, varacl aclitem[]); create variable pg_variable as pg_variable; let pg_variable = row (18041, 10116, '0/25137B0','pg_variable', 2200, 10,-1,0, NULL)::pg_variable; select pg_variable.oid from pg_variable where pg_variable.oid = pg_variable.oid; this query, the WHERE clause, it's really hard to distinguish session variable or column reference. I am not sure if this is fine or not.
On Fri, Feb 7, 2025 at 3:25 PM Pavel Stehule <pavel.stehule@gmail.com> wrote: > Hi The following review is based on v20250117. pg_dump order seems not right. CREATE FUNCTION public.test11(text) RETURNS text LANGUAGE sql AS $$select v4 $$; CREATE VARIABLE public.v4 AS text; first dump function then variable. restore would fail. we should first dump variables then function. probably placed it right after CREATE DOMAIN/CREATE TYPE drop table if exists t3; create variable v4 as text; let v4 = 'hello'; CREATE TABLE t3 (a timestamp, v4 text); INSERT INTO t3 SELECT i FROM generate_series('2020-01-01'::timestamp, '2020-12-31'::timestamp, '10 minute'::interval) s(i); ANALYZE t3; create or replace function test11(text) returns text as $$select v4 $$ language sql; CREATE STATISTICS s4 (ndistinct) ON test11(v4), test11(v4 || 'h') FROM t3; this "CREATE STATISTICS s4..." should error out? any objects built on top of functions that use variables should be marked as volatile. and we should also consider the implications of it.
Hi
forced rebase
Regards
Pavel
Вложения
- v20250220-0021-pg_restore-A-variable.patch
- v20250220-0020-transactional-variables.patch
- v20250220-0017-plpgsql-implementation-for-LET-statement.patch
- v20250220-0018-expression-with-session-variables-can-be-inlined.patch
- v20250220-0019-this-patch-changes-error-message-column-doesn-t-exis.patch
- v20250220-0016-allow-parallel-execution-queries-with-session-variab.patch
- v20250220-0015-allow-read-an-value-of-session-variable-directly-fro.patch
- v20250220-0014-Implementation-of-NOT-NULL-and-IMMUTABLE-clauses.patch
- v20250220-0013-Implementation-of-DEFAULT-clause-default-expressions.patch
- v20250220-0012-Implementation-ON-TRANSACTION-END-RESET-clause.patch
- v20250220-0011-implementation-of-temporary-session-variables.patch
- v20250220-0010-PREPARE-LET-support.patch
- v20250220-0009-EXPLAIN-LET-support.patch
- v20250220-0007-GUC-session_variables_ambiguity_warning.patch
- v20250220-0005-memory-cleaning-after-DROP-VARIABLE.patch
- v20250220-0008-variable-fence-syntax-support-and-variable-fence-usa.patch
- v20250220-0006-plpgsql-tests.patch
- v20250220-0004-DISCARD-VARIABLES.patch
- v20250220-0003-function-pg_session_variables-for-cleaning-tests.patch
- v20250220-0001-Enhancing-catalog-for-support-session-variables-and-.patch
- v20250220-0002-Storage-for-session-variables-and-SQL-interface.patch
Hi
fix regress tests after 95dbd827f2edc4d10bebd7e840a0bd6782cf69b7
Regards
Pavel
Вложения
- v20250301-0003-function-pg_session_variables-for-cleaning-tests.patch
- v20250301-0001-Enhancing-catalog-for-support-session-variables-and-.patch
- v20250301-0004-DISCARD-VARIABLES.patch
- v20250301-0005-memory-cleaning-after-DROP-VARIABLE.patch
- v20250301-0002-Storage-for-session-variables-and-SQL-interface.patch
- v20250301-0007-GUC-session_variables_ambiguity_warning.patch
- v20250301-0010-PREPARE-LET-support.patch
- v20250301-0009-EXPLAIN-LET-support.patch
- v20250301-0006-plpgsql-tests.patch
- v20250301-0008-variable-fence-syntax-support-and-variable-fence-usa.patch
- v20250301-0013-Implementation-of-DEFAULT-clause-default-expressions.patch
- v20250301-0012-Implementation-ON-TRANSACTION-END-RESET-clause.patch
- v20250301-0014-Implementation-of-NOT-NULL-and-IMMUTABLE-clauses.patch
- v20250301-0011-implementation-of-temporary-session-variables.patch
- v20250301-0015-allow-read-an-value-of-session-variable-directly-fro.patch
- v20250301-0016-allow-parallel-execution-queries-with-session-variab.patch
- v20250301-0017-plpgsql-implementation-for-LET-statement.patch
- v20250301-0018-expression-with-session-variables-can-be-inlined.patch
- v20250301-0021-pg_restore-A-variable.patch
- v20250301-0019-this-patch-changes-error-message-column-doesn-t-exis.patch
- v20250301-0020-transactional-variables.patch
Hi
I was asked for sending a reduced patchset
Regards
Pavel
Вложения
- v20250317-0003-function-pg_session_variables-for-cleaning-tests.patch
- v20250317-0002-Storage-for-session-variables-and-SQL-interface.patch
- v20250317-0005-memory-cleaning-after-DROP-VARIABLE.patch
- v20250317-0004-DISCARD-VARIABLES.patch
- v20250317-0006-plpgsql-tests.patch
- v20250317-0001-Enhancing-catalog-for-support-session-variables-and-.patch
- v20250317-0007-GUC-session_variables_ambiguity_warning.patch
- v20250317-0008-variable-fence-syntax-support-and-variable-fence-usa.patch
Em seg., 17 de mar. de 2025 às 15:33, Pavel Stehule <pavel.stehule@gmail.com> escreveu:
I was asked for sending a reduced patchset
Would be good to explain what this reduced patchset is.
Complete patch contains this and that
Reduced patch contains only this.
Regards
Marcos
Hi
po 17. 3. 2025 v 21:53 odesílatel Marcos Pegoraro <marcos@f10.com.br> napsal:
Em seg., 17 de mar. de 2025 às 15:33, Pavel Stehule <pavel.stehule@gmail.com> escreveu:I was asked for sending a reduced patchsetWould be good to explain what this reduced patchset is.Complete patch contains this and thatReduced patch contains only this.
Reduced patch contains:
* possibility to create and drop session variables (support for catalog pg_variable and related operations)
* possibility to set the session variable (command LET) and possibility to use session variable in the query
* access right support
* support for DISCARD command
* memory cleaning at transaction end when the variable is dropped
* warning when variable is shadowed by column
* introduction of variable's fences - syntax VARIABLE(varname)
Complete patch contains plus
* LET can be described by EXPLAIN
* LET can be prepared statement
* temporary session variables
* RESET at transaction end
* implementation of DEFAULT value for the variable
* implementation IMMUTABLE and NOT NULL clauses for the variable
* variable can be used as an argument of CALL statement (and doesn't block simple evaluation in plpgsql)
* used variable doesn't block with parallel execution
* LET from plpgsql can use simple expression evaluation (performance optimization for PL/pgSQL)
* variables doesn't block inlining SQL functions
* fix message "column doesn't exist" to "column or variable doesn't exist"
* support for transactional variables (content can be transactional)
* possibility to specify the name of restored variable for pg_restore
Regards
Pavel
RegardsMarcos
Hi
necessary rebase
Regards
Pavel
Вложения
- v20250402-0007-GUC-session_variables_ambiguity_warning.patch
- v20250402-0006-plpgsql-tests.patch
- v20250402-0005-memory-cleaning-after-DROP-VARIABLE.patch
- v20250402-0004-DISCARD-VARIABLES.patch
- v20250402-0008-variable-fence-syntax-support-and-variable-fence-usa.patch
- v20250402-0003-function-pg_session_variables-for-cleaning-tests.patch
- v20250402-0002-Storage-for-session-variables-and-SQL-interface.patch
- v20250402-0001-Enhancing-catalog-for-support-session-variables-and-.patch
Hi
only rebase
Regards
Pavel
Вложения
- v20250405-0008-variable-fence-syntax-support-and-variable-fence-usa.patch
- v20250405-0006-plpgsql-tests.patch
- v20250405-0007-GUC-session_variables_ambiguity_warning.patch
- v20250405-0005-memory-cleaning-after-DROP-VARIABLE.patch
- v20250405-0004-DISCARD-VARIABLES.patch
- v20250405-0003-function-pg_session_variables-for-cleaning-tests.patch
- v20250405-0002-Storage-for-session-variables-and-SQL-interface.patch
- v20250405-0001-Enhancing-catalog-for-support-session-variables-and-.patch
On Thu, May 15, 2025 at 08:48:37AM +0200, Pavel Stehule wrote: > Hi > > fresh rebase I will again ask why this patch set is being reposted when there is no plan to apply it to git master? -- Bruce Momjian <bruce@momjian.us> https://momjian.us EDB https://enterprisedb.com Do not let urgent matters crowd out time for investment in the future.
Em ter., 20 de mai. de 2025 às 11:56, Bruce Momjian <bruce@momjian.us> escreveu:
I will again ask why this patch set is being reposted when there is no
plan to apply it to git master
Too bad. I would love to have this functionality, from the user's point of view there are problems where it would solve them wonderfully. I don't know technically of what prevents it from being natively on core, but it would be great, it would definitely be.
regards
Marcos
On Tue, May 20, 2025 at 01:33:18PM -0300, Marcos Pegoraro wrote: > Em ter., 20 de mai. de 2025 às 11:56, Bruce Momjian <bruce@momjian.us> > escreveu: > > I will again ask why this patch set is being reposted when there is no > plan to apply it to git master > > Too bad. I would love to have this functionality, from the user's point of view > there are problems where it would solve them wonderfully. I don't know > technically of what prevents it from being natively on core, but it would be > great, it would definitely be. My only point is that we should only be using email lists for work that is being actively worked on to be added to community Postgres. There has been talk of a trimmed-down version of this being applied, but I don't see any work in that direction. This patch should be moved to a separate location where perhaps people can subscribe to updates when they are posted, perhaps github. -- Bruce Momjian <bruce@momjian.us> https://momjian.us EDB https://enterprisedb.com Do not let urgent matters crowd out time for investment in the future.
> On 20 May 2025, at 18:39, Bruce Momjian <bruce@momjian.us> wrote: > > On Tue, May 20, 2025 at 01:33:18PM -0300, Marcos Pegoraro wrote: >> Em ter., 20 de mai. de 2025 às 11:56, Bruce Momjian <bruce@momjian.us> >> escreveu: >> >> I will again ask why this patch set is being reposted when there is no >> plan to apply it to git master >> >> Too bad. I would love to have this functionality, from the user's point of view >> there are problems where it would solve them wonderfully. I don't know >> technically of what prevents it from being natively on core, but it would be >> great, it would definitely be. > > My only point is that we should only be using email lists for work that > is being actively worked on to be added to community Postgres. There > has been talk of a trimmed-down version of this being applied, but I > don't see any work in that direction. > > This patch should be moved to a separate location where perhaps people > can subscribe to updates when they are posted, perhaps github. As a project with no roadmap governed by open forum consensus I don't think we have any right to tell community members what they can or cannot work on here, any technical discussion which conforms with our published policies should be welcome. If Pavel want's to continue rebasing his patchset here then he has, IMHO, every right to do so. Whether or not a committer will show interest at some point is another thing, but we are seeing a very good role-model for taking responsibility for ones work here at the very least =) -- Daniel Gustafsson
On Tue, May 20, 2025 at 08:47:36PM +0200, Daniel Gustafsson wrote: > > On 20 May 2025, at 18:39, Bruce Momjian <bruce@momjian.us> wrote: > > My only point is that we should only be using email lists for work that > > is being actively worked on to be added to community Postgres. There > > has been talk of a trimmed-down version of this being applied, but I > > don't see any work in that direction. > > > > This patch should be moved to a separate location where perhaps people > > can subscribe to updates when they are posted, perhaps github. > > As a project with no roadmap governed by open forum consensus I don't think we > have any right to tell community members what they can or cannot work on here, > any technical discussion which conforms with our published policies should be > welcome. If Pavel want's to continue rebasing his patchset here then he has, > IMHO, every right to do so. > > Whether or not a committer will show interest at some point is another thing, > but we are seeing a very good role-model for taking responsibility for ones > work here at the very least =) Well, we do have a right, e.g., we would not allow someone to repeatedly post patches for a Postgres extension we don't manage, or the jdbc driver. I also don't think we would allow someone to continue posting patches for a feature we have decided to reject, and I think we have decided to reject the patch in in its current form. I think we might accept a trimmed-down version, but I don't see the patch moving in that direction. Now, of course, if I am the only one who feels this way, I can suppress these emails on my end. -- Bruce Momjian <bruce@momjian.us> https://momjian.us EDB https://enterprisedb.com Do not let urgent matters crowd out time for investment in the future.
Hi
út 20. 5. 2025 v 18:39 odesílatel Bruce Momjian <bruce@momjian.us> napsal:
On Tue, May 20, 2025 at 01:33:18PM -0300, Marcos Pegoraro wrote:
> Em ter., 20 de mai. de 2025 às 11:56, Bruce Momjian <bruce@momjian.us>
> escreveu:
>
> I will again ask why this patch set is being reposted when there is no
> plan to apply it to git master
>
> Too bad. I would love to have this functionality, from the user's point of view
> there are problems where it would solve them wonderfully. I don't know
> technically of what prevents it from being natively on core, but it would be
> great, it would definitely be.
My only point is that we should only be using email lists for work that
is being actively worked on to be added to community Postgres. There
has been talk of a trimmed-down version of this being applied, but I
don't see any work in that direction.
I sent a reduced version a few months ago - from 21 patches to 8 (and it can be reduced to six if we postpone tools for detection ambiguity).
The timing was not perfect - the focus was and it is concentrated to finish pg18.
I am very sorry if this topic and patches bother anyone. I am afraid if I close it to some personal github, it will not be visible, and I am sure this
feature is missing in Postgres. Today we have few workarounds. Some workarounds are not available everywhere, some workarounds cannot
be used for security. With integrated solutions some scenarios can be done more easily, more secure, faster, more comfortable. It is true, so
mentioned scenarios are not "hot" today. Stored procedures or RLS or migration procedures from other databases are not extra common. But
who uses it, then he misses session variables.
This topic is difficult, because there is no common solution. SQL/PSM is almost dead. T-SQL (and MySQL) design is weak and cannot be used for security.
Oracle's design is joined with just one environment. And although almost all widely used databases have supported session variables for decades, no one design
is perfect. Proposed design is not perfect too (it introduces possible ambiguity) , but I think it can support most wanted use cases (can be enhanced in future),
and it is consistent with Postgres. There are more ways to reduce risk of unwanted ambiguity to zero. But it increases the size of the patch.
Regards
Pavel
This patch should be moved to a separate location where perhaps people
can subscribe to updates when they are posted, perhaps github.
--
Bruce Momjian <bruce@momjian.us> https://momjian.us
EDB https://enterprisedb.com
Do not let urgent matters crowd out time for investment in the future.
On Tue, May 20, 2025 at 10:28:31PM +0200, Pavel Stehule wrote: > út 20. 5. 2025 v 18:39 odesílatel Bruce Momjian <bruce@momjian.us> napsal: > I sent a reduced version a few months ago - from 21 patches to 8 (and it can be > reduced to six if we postpone tools for detection ambiguity). > The timing was not perfect - the focus was and it is concentrated to finish > pg18. It was not clear to me that this patch set was being reduced to make it more likely it would be accepted? I thought it was the same patch set since 20??. > I am very sorry if this topic and patches bother anyone. I am afraid if I close > it to some personal github, it will not be visible, and I am sure this > feature is missing in Postgres. Today we have few workarounds. Some workarounds > are not available everywhere, some workarounds cannot > be used for security. With integrated solutions some scenarios can be done more > easily, more secure, faster, more comfortable. It is true, so > mentioned scenarios are not "hot" today. Stored procedures or RLS or migration > procedures from other databases are not extra common. But > who uses it, then he misses session variables. Understood. If people feel it is progressing toward acceptance, I certainly withdraw my objection and apologize. -- Bruce Momjian <bruce@momjian.us> https://momjian.us EDB https://enterprisedb.com Do not let urgent matters crowd out time for investment in the future.
On Tue, May 20, 2025 at 10:28:31PM +0200, Pavel Stehule wrote: > This topic is difficult, because there is no common solution. SQL/PSM is > almost dead. T-SQL (and MySQL) design is weak and cannot be used for > security. > Oracle's design is joined with just one environment. And although almost > all widely used databases have supported session variables for decades, no > one design > is perfect. Proposed design is not perfect too (it introduces possible > ambiguity) , but I think it can support most wanted use cases (can be > enhanced in future), > and it is consistent with Postgres. There are more ways to reduce risk of > unwanted ambiguity to zero. But it increases the size of the patch. One thing that I keep hearing about this feature is that this would be really helpful for migration from Oracle to PostgreSQL, helping a lot with rewrites of pl/pgsql functions. There is one page on the wiki about private variables, dating back to 2016: https://wiki.postgresql.org/wiki/CREATE_PRIVATE_VARIABLE Perhaps it would help to summarize a bit the pros and cons of existing implementations to drive which implementation would be the most suited on a wiki page? The way standards are defined is by overwriting existing standards, and we don't have one in the SQL specification. It's hard to say if there will be one at some point, but if the main SQL products around the world have one, it pretty much is a point in favor of having a standard. Another possible angle that could be taken is to invest in a proposal for the SQL committee to consider, forcing an actual standard that PostgreSQL could rely on rather than having one behavior implemented to have it standard-incompatible a few years after. And luckily, we have Vik Fearing and Peter Eisentraut in this community who invest time and resources in this area. FWIW, I do agree with the opinion that if you want to propose rebased versions of this patch set on a periodic basis, you are free to do so. This is the core concept of an open community. In terms of my committer time, I'm pretty much already booked in terms of features planned for the next release, so I guess that I won't be able to invest time on this thread. Just saying. I know that this patch set has been discussed at FOSDEM at some point, so others may be able to comment more about that. That's just one opinion among many others. -- Michael
Вложения
st 21. 5. 2025 v 2:21 odesílatel Michael Paquier <michael@paquier.xyz> napsal:
On Tue, May 20, 2025 at 10:28:31PM +0200, Pavel Stehule wrote:
> This topic is difficult, because there is no common solution. SQL/PSM is
> almost dead. T-SQL (and MySQL) design is weak and cannot be used for
> security.
> Oracle's design is joined with just one environment. And although almost
> all widely used databases have supported session variables for decades, no
> one design
> is perfect. Proposed design is not perfect too (it introduces possible
> ambiguity) , but I think it can support most wanted use cases (can be
> enhanced in future),
> and it is consistent with Postgres. There are more ways to reduce risk of
> unwanted ambiguity to zero. But it increases the size of the patch.
One thing that I keep hearing about this feature is that this would be
really helpful for migration from Oracle to PostgreSQL, helping a lot
with rewrites of pl/pgsql functions.
There is one page on the wiki about private variables, dating back to
2016:
https://wiki.postgresql.org/wiki/CREATE_PRIVATE_VARIABLE
I wrote mail
and there is another wiki page https://wiki.postgresql.org/wiki/Variable_Design
Perhaps it would help to summarize a bit the pros and cons of existing
implementations to drive which implementation would be the most suited
on a wiki page? The way standards are defined is by overwriting
existing standards, and we don't have one in the SQL specification.
It's hard to say if there will be one at some point, but if the main
SQL products around the world have one, it pretty much is a point in
favor of having a standard.
Although it is maybe a peccant idea - I can imagine two different implementations of server side session variables with different syntaxes
(and different advantages and disadvantages, and different use cases). The implementations are not going against, but we should to accept
fact, so one feature is implemented twice. We should choose just one, that will be implemented first. Proposed helps with migration from
PL/SQL.
Another possible angle that could be taken is to invest in a proposal
for the SQL committee to consider, forcing an actual standard that
PostgreSQL could rely on rather than having one behavior implemented
to have it standard-incompatible a few years after. And luckily, we
have Vik Fearing and Peter Eisentraut in this community who invest
time and resources in this area.
Theoretically the proposed design is a subset of implementation from DB2 - I designed it without knowledge of this DB2 feature. But without
introduction of concept of modules (that is partially redundant to schemas), this design is very natural and I am very sure, so there is not
another way, how to design it. We can ask Peter or Vik about real possibilities in this area. I have not any information from this area, just
I haven't seen the changes in SQL/PSM for decades, so I didn't think about it.
FWIW, I do agree with the opinion that if you want to propose rebased
versions of this patch set on a periodic basis, you are free to do so.
This is the core concept of an open community. In terms of my
committer time, I'm pretty much already booked in terms of features
planned for the next release, so I guess that I won't be able to
invest time on this thread. Just saying.
thank you for an info
I know that this patch set has been discussed at FOSDEM at some point,
so others may be able to comment more about that. That's just one
opinion among many others.
--
Michael
Hi
út 19. 11. 2024 v 20:14 odesílatel Pavel Stehule <pavel.stehule@gmail.com> napsal:
HiI wrote POC of VARIABLE(varname) syntax supporthere is a copy from regress testSET session_variables_ambiguity_warning TO on;
SET session_variables_use_fence_warning_guard TO on;
SET search_path TO 'public';
CREATE VARIABLE a AS int;
LET a = 10;
CREATE TABLE test_table(a int, b int);
INSERT INTO test_table VALUES(20, 20);
-- no warning
SELECT a;
a..
----
10
(1 row)
-- warning variable is shadowed
SELECT a, b FROM test_table;
WARNING: session variable "a" is shadowed
LINE 1: SELECT a, b FROM test_table;
^
DETAIL: Session variables can be shadowed by columns, routine's variables and routine's arguments with the same name.
a | b..
----+----
20 | 20
(1 row)
-- no warning
SELECT variable(a) FROM test_table;
a..
----
10
(1 row)
ALTER TABLE test_table DROP COLUMN a;
-- warning - variable fence is not used
SELECT a, b FROM test_table;
WARNING: session variable "a" is not used inside variable fence
LINE 1: SELECT a, b FROM test_table;
^
DETAIL: The collision of session variable' names and column names is possible.
a | b..
----+----
10 | 20
(1 row)
-- no warning
SELECT variable(a), b FROM test_table;
a | b..
----+----
10 | 20
(1 row)
DROP VARIABLE a;
DROP TABLE test_table;
SET session_variables_ambiguity_warning TO DEFAULT;
SET session_variables_use_fence_warning_guard TO DEFAULT;
SET search_path TO DEFAULT;
Last discussion is related to reducing the size of the session variable patch set.
I have an idea to use variable's fencing more aggressively from the start, and then we can reduce it in future. This should not break issues with compatibility and doesn't need some like version flags.
The real problem of proposed session variables is possible collisions between session variables identifiers and table or columns identifiers. I designed some tools to minimize the risk of unwanted collisions, but these tools increase the size of code and don't reduce the complexity of the patch and tests. The proposed change probably doesn't reduce a lot of code, but can reduce some tests, and mainly possible risk of some unwanted impact - at the end it can be less work for reviewers and less stress for committers - and the implementation can be divided to allone workable following steps.
Step 1
=====
So the main change is the hard requirement for usage variable's fence everywhere where collisions are possible - and then in the first step, the collisions will not be possible, and then we don't need it to solve, and we don't need to test it.
CREATE VARIABLE public.foo AS int;
LET foo = 10;
SELECT VARIABLE(foo);
DO $$
BEGIN
RAISE NOTICE '% %', VARIABLE(foo), VARIABLE(public.foo);
END;
$$;
Step 2
=====
Necessity of usage variable fencing in PL/pgSQL can be a problem for migration from PL/SQL. But this can be solved separately by using SPI params hooks - similar to how PL/pgSQL works with PL/pgSQL variables. In this step we can push optimization for fast execution of the LET statement or optimization of usage variables in queries.
After this step will be possible:
DO $$
BEGIN
RAISE NOTICE '% %', foo, VARIABLE(public.foo);
END;
$$;
SELECT VARIABLE(foo);
No other visible change in this step. WIth this step the people who do migration form Oracle and PL/pgSQL developers will be very happy. They don't need more. There can be collisions, but the collisions can be limited just to PL/pgSQL scope, and we can use already implemented mechanisms.
Step 3
=====
We can talk in future about less requirement of usage variable fencing in queries. This needs to introduce some form of detection collisions and how they should be solved (outside PL/pgSQL).
We can talk about other features like temporal, default values, transactional, etc ...
This proposal doesn't reduce lines of code, but significantly reduces possible impacts of introducing session variables to other parts of SQL. Moreover, it allows us to separate some
work and related discussion into separate blocks - any block can be implemented in different major pg releases.I think a lot of users will be very happy just with step 1 and step 2, and anything else can be discussed in future.
Is this plan acceptable?
Regards
Pavel
RegardsPavel
On Wed, May 21, 2025 at 09:12:54AM +0200, Pavel Stehule wrote: > Last discussion is related to reducing the size of the session variable patch > set. > > I have an idea to use variable's fencing more aggressively from the start, and > then we can reduce it in future. This should not break issues with > compatibility and doesn't need some like version flags. > > The real problem of proposed session variables is possible collisions between > session variables identifiers and table or columns identifiers. I designed some > tools to minimize the risk of unwanted collisions, but these tools increase the > size of code and don't reduce the complexity of the patch and tests. The > proposed change probably doesn't reduce a lot of code, but can reduce some > tests, and mainly possible risk of some unwanted impact - at the end it can be > less work for reviewers and less stress for committers - and the implementation > can be divided to allone workable following steps. Yes, I remember the discussions about how the creation of server variables could break existing queries. Our scoping rules are already complex, so adding another scope would add a lot of complexity. > Step 1 > ===== > > So the main change is the hard requirement for usage variable's fence > everywhere where collisions are possible - and then in the first step, the > collisions will not be possible, and then we don't need it to solve, and we > don't need to test it. > > CREATE VARIABLE public.foo AS int; > LET foo = 10; > SELECT VARIABLE(foo); Yes, I can see how adding fencing like VARIABLE() would simplify things. > Step 2 > ===== > Necessity of usage variable fencing in PL/pgSQL can be a problem for migration > from PL/SQL. But this can be solved separately by using SPI params hooks - > similar to how PL/pgSQL works with PL/pgSQL variables. In this step we can push > optimization for fast execution of the LET statement or optimization of usage > variables in queries. Yes, there is already going to be migration requirements in moving from PL/SQL to PL/pgSQL, so the requirement to add VARIABLE() seems minimal. > After this step will be possible: > > DO $$ > BEGIN > RAISE NOTICE '% %', foo, VARIABLE(public.foo); > END; > $$; > > SELECT VARIABLE(foo); > > No other visible change in this step. WIth this step the people who do > migration form Oracle and PL/pgSQL developers will be very happy. They don't > need more. There can be collisions, but the collisions can be limited just to > PL/pgSQL scope, and we can use already implemented mechanisms. > > Step 3 > ===== > We can talk in future about less requirement of usage variable fencing in > queries. This needs to introduce some form of detection collisions and how they > should be solved (outside PL/pgSQL). > We can talk about other features like temporal, default values, transactional, > etc ... I feel that if we haven't found a good solution to this in 13 years, we should assume it is unsolvable and just accept an imperfect solution. -- Bruce Momjian <bruce@momjian.us> https://momjian.us EDB https://enterprisedb.com Do not let urgent matters crowd out time for investment in the future.
On Wed, May 21, 2025 at 07:49:34AM +0200, Pavel Stehule wrote: > st 21. 5. 2025 v 2:21 odesílatel Michael Paquier <michael@paquier.xyz> napsal: > One thing that I keep hearing about this feature is that this would be > really helpful for migration from Oracle to PostgreSQL, helping a lot > with rewrites of pl/pgsql functions. > > There is one page on the wiki about private variables, dating back to > 2016: > https://wiki.postgresql.org/wiki/CREATE_PRIVATE_VARIABLE > > I wrote mail > > https://www.postgresql.org/message-id/ > CAFj8pRB8kdWQCdN2X1_63c58+07Oy4Z+ruDK_xPTUP+Pe8R2Pw@mail.gmail.com > > and there is another wiki page https://wiki.postgresql.org/wiki/Variable_Design Yes, these URLs are very helpful, thanks. -- Bruce Momjian <bruce@momjian.us> https://momjian.us EDB https://enterprisedb.com Do not let urgent matters crowd out time for investment in the future.
Hi
I found a small problem in the pg_session_variables function. I expected syscache to be flushed for recent catalog changes
before any usage of this function. But it is not always true. When I used the DCATCACHE_FORCE_RELEASE build option, I got
different results from isolation tests. Fix is simple - just call AcceptInvalidationMessages(); before touching syscache in this
function.
Note: pg_session_variables is a debug function - it shows entries of a hash table with session variables used in the current session.
The result's attribute with information if the entry is related to a valid or to invalid value (related tuple in pg_variable exists or not) was not correct.
Regards
Pavel
Вложения
- v20250604-0014-memory-cleaning-after-DROP-VARIABLE.patch
- v20250604-0015-plpgsql-tests.patch
- v20250604-0013-DISCARD-VARIABLES.patch
- v20250604-0011-LET-command-assign-a-result-of-expression-to-the-ses.patch
- v20250604-0012-function-pg_session_variables-for-cleaning-tests.patch
- v20250604-0010-svariableReceiver.patch
- v20250604-0009-fill-an-auxiliary-buffer-with-values-of-session-vari.patch
- v20250604-0008-collect-session-variables-used-in-plan-and-assign-pa.patch
- v20250604-0007-local-HASHTAB-for-currently-used-session-variables-a.patch
- v20250604-0006-session-variable-fences-parsing.patch
- v20250604-0005-support-of-session-variables-for-pg_dump.patch
- v20250604-0004-support-of-session-variables-for-psql.patch
- v20250604-0003-GRANT-REVOKE-variable.patch
- v20250604-0001-introduce-new-class-catalog-pg_variable.patch
- v20250604-0002-CREATE-DROP-ALTER-VARIABLE.patch
Hi
I run pgindent - the changes are mostly only in comments
Regards
Pavel
Вложения
- 0015-plpgsql-tests.patch
- 0014-memory-cleaning-after-DROP-VARIABLE.patch
- 0011-LET-command-assign-a-result-of-expression-to-the-ses.patch
- 0013-DISCARD-VARIABLES.patch
- 0010-svariableReceiver.patch
- 0012-function-pg_session_variables-for-cleaning-tests.patch
- 0008-collect-session-variables-used-in-plan-and-assign-pa.patch
- 0009-fill-an-auxiliary-buffer-with-values-of-session-vari.patch
- 0007-local-HASHTAB-for-currently-used-session-variables-a.patch
- 0005-support-of-session-variables-for-pg_dump.patch
- 0006-session-variable-fences-parsing.patch
- 0003-GRANT-REVOKE-variable.patch
- 0004-support-of-session-variables-for-psql.patch
- 0002-CREATE-DROP-ALTER-VARIABLE.patch
- 0001-introduce-new-class-catalog-pg_variable.patch
Hi
* fresh rebase
+ new small test of usage LET from extended query protocol (test of usage of parameters)
+ few notes in patch 11 commit message about reasons why LET keyword was used instead SET for assign command
Regards
Pavel
Вложения
- v20250625-0015-plpgsql-tests.patch
- v20250625-0012-function-pg_session_variables-for-cleaning-tests.patch
- v20250625-0013-DISCARD-VARIABLES.patch
- v20250625-0011-LET-command-assign-a-result-of-expression-to-the-ses.patch
- v20250625-0014-memory-cleaning-after-DROP-VARIABLE.patch
- v20250625-0009-fill-an-auxiliary-buffer-with-values-of-session-vari.patch
- v20250625-0010-svariableReceiver.patch
- v20250625-0007-local-HASHTAB-for-currently-used-session-variables-a.patch
- v20250625-0008-collect-session-variables-used-in-plan-and-assign-pa.patch
- v20250625-0004-support-of-session-variables-for-psql.patch
- v20250625-0006-session-variable-fences-parsing.patch
- v20250625-0005-support-of-session-variables-for-pg_dump.patch
- v20250625-0003-GRANT-REVOKE-variable.patch
- v20250625-0002-CREATE-DROP-ALTER-VARIABLE.patch
- v20250625-0001-introduce-new-class-catalog-pg_variable.patch
Hi
just fresh rebase
Regards
Pavel
Вложения
- 0015-plpgsql-tests.patch
- 0013-DISCARD-VARIABLES.patch
- 0014-memory-cleaning-after-DROP-VARIABLE.patch
- 0011-LET-command-assign-a-result-of-expression-to-the-ses.patch
- 0012-function-pg_session_variables-for-cleaning-tests.patch
- 0010-svariableReceiver.patch
- 0008-collect-session-variables-used-in-plan-and-assign-pa.patch
- 0007-local-HASHTAB-for-currently-used-session-variables-a.patch
- 0009-fill-an-auxiliary-buffer-with-values-of-session-vari.patch
- 0006-session-variable-fences-parsing.patch
- 0005-support-of-session-variables-for-pg_dump.patch
- 0004-support-of-session-variables-for-psql.patch
- 0003-GRANT-REVOKE-variable.patch
- 0002-CREATE-DROP-ALTER-VARIABLE.patch
- 0001-introduce-new-class-catalog-pg_variable.patch
Hi
rebase after e2debb6
Regards
Pavel
Вложения
- v20250722-0014-memory-cleaning-after-DROP-VARIABLE.patch
- v20250722-0011-LET-command-assign-a-result-of-expression-to-the-ses.patch
- v20250722-0012-function-pg_session_variables-for-cleaning-tests.patch
- v20250722-0013-DISCARD-VARIABLES.patch
- v20250722-0015-plpgsql-tests.patch
- v20250722-0010-svariableReceiver.patch
- v20250722-0009-fill-an-auxiliary-buffer-with-values-of-session-vari.patch
- v20250722-0007-local-HASHTAB-for-currently-used-session-variables-a.patch
- v20250722-0008-collect-session-variables-used-in-plan-and-assign-pa.patch
- v20250722-0006-session-variable-fences-parsing.patch
- v20250722-0005-support-of-session-variables-for-pg_dump.patch
- v20250722-0004-support-of-session-variables-for-psql.patch
- v20250722-0003-GRANT-REVOKE-variable.patch
- v20250722-0001-introduce-new-class-catalog-pg_variable.patch
- v20250722-0002-CREATE-DROP-ALTER-VARIABLE.patch
Hi
fresh rebase - testing farms reports failure
Regards
Pavel
Вложения
- v20250723-0015-plpgsql-tests.patch
- v20250723-0011-LET-command-assign-a-result-of-expression-to-the-ses.patch
- v20250723-0012-function-pg_session_variables-for-cleaning-tests.patch
- v20250723-0013-DISCARD-VARIABLES.patch
- v20250723-0014-memory-cleaning-after-DROP-VARIABLE.patch
- v20250723-0009-fill-an-auxiliary-buffer-with-values-of-session-vari.patch
- v20250723-0010-svariableReceiver.patch
- v20250723-0008-collect-session-variables-used-in-plan-and-assign-pa.patch
- v20250723-0006-session-variable-fences-parsing.patch
- v20250723-0007-local-HASHTAB-for-currently-used-session-variables-a.patch
- v20250723-0005-support-of-session-variables-for-pg_dump.patch
- v20250723-0003-GRANT-REVOKE-variable.patch
- v20250723-0004-support-of-session-variables-for-psql.patch
- v20250723-0002-CREATE-DROP-ALTER-VARIABLE.patch
- v20250723-0001-introduce-new-class-catalog-pg_variable.patch
Hi
fresh rebase after 4e23c9ef65accde7eb3e56aa28d50ae5cf79b64b
Regards
Pavel
Вложения
- v20250805-0014-memory-cleaning-after-DROP-VARIABLE.patch
- v20250805-0012-function-pg_session_variables-for-cleaning-tests.patch
- v20250805-0015-plpgsql-tests.patch
- v20250805-0013-DISCARD-VARIABLES.patch
- v20250805-0011-LET-command-assign-a-result-of-expression-to-the-ses.patch
- v20250805-0010-svariableReceiver.patch
- v20250805-0009-fill-an-auxiliary-buffer-with-values-of-session-vari.patch
- v20250805-0008-collect-session-variables-used-in-plan-and-assign-pa.patch
- v20250805-0007-local-HASHTAB-for-currently-used-session-variables-a.patch
- v20250805-0006-session-variable-fences-parsing.patch
- v20250805-0004-support-of-session-variables-for-psql.patch
- v20250805-0005-support-of-session-variables-for-pg_dump.patch
- v20250805-0002-CREATE-DROP-ALTER-VARIABLE.patch
- v20250805-0003-GRANT-REVOKE-variable.patch
- v20250805-0001-introduce-new-class-catalog-pg_variable.patch
Hi
fix regress tests after 71ea0d6795438f95f4ee6e35867058c44b270d51
Regards
Pavel
Вложения
- v20250813-0015-plpgsql-tests.patch
- v20250813-0013-DISCARD-VARIABLES.patch
- v20250813-0014-memory-cleaning-after-DROP-VARIABLE.patch
- v20250813-0012-function-pg_session_variables-for-cleaning-tests.patch
- v20250813-0011-LET-command-assign-a-result-of-expression-to-the-ses.patch
- v20250813-0010-svariableReceiver.patch
- v20250813-0009-fill-an-auxiliary-buffer-with-values-of-session-vari.patch
- v20250813-0008-collect-session-variables-used-in-plan-and-assign-pa.patch
- v20250813-0007-local-HASHTAB-for-currently-used-session-variables-a.patch
- v20250813-0006-session-variable-fences-parsing.patch
- v20250813-0004-support-of-session-variables-for-psql.patch
- v20250813-0003-GRANT-REVOKE-variable.patch
- v20250813-0005-support-of-session-variables-for-pg_dump.patch
- v20250813-0002-CREATE-DROP-ALTER-VARIABLE.patch
- v20250813-0001-introduce-new-class-catalog-pg_variable.patch
Hi
rebase after 325fc0ab14d11fc87da594857ffbb6636affe7c0
Regards
Pavel
Вложения
- v20250829-0015-plpgsql-tests.patch
- v20250829-0014-memory-cleaning-after-DROP-VARIABLE.patch
- v20250829-0011-LET-command-assign-a-result-of-expression-to-the-ses.patch
- v20250829-0012-function-pg_session_variables-for-cleaning-tests.patch
- v20250829-0013-DISCARD-VARIABLES.patch
- v20250829-0010-svariableReceiver.patch
- v20250829-0008-collect-session-variables-used-in-plan-and-assign-pa.patch
- v20250829-0009-fill-an-auxiliary-buffer-with-values-of-session-vari.patch
- v20250829-0007-local-HASHTAB-for-currently-used-session-variables-a.patch
- v20250829-0006-session-variable-fences-parsing.patch
- v20250829-0005-support-of-session-variables-for-pg_dump.patch
- v20250829-0003-GRANT-REVOKE-variable.patch
- v20250829-0004-support-of-session-variables-for-psql.patch
- v20250829-0002-CREATE-DROP-ALTER-VARIABLE.patch
- v20250829-0001-introduce-new-class-catalog-pg_variable.patch
Hi
minor change (after private talk with Jim Jones)
renaming function `pg_session_variables` to `pg_get_session_variables_memory`
renaming out parameter of this function `removed` to `dropped`
+ regress test plpgsql - plpgsql routines has not strong dependency to session variables (same dependency like to other database objects)
Regards
Pavel
Вложения
- v20250913-0012-function-pg_get_session_variables_memory-for-cleanin.patch
- v20250913-0013-DISCARD-VARIABLES.patch
- v20250913-0011-LET-command-assign-a-result-of-expression-to-the-ses.patch
- v20250913-0014-memory-cleaning-after-DROP-VARIABLE.patch
- v20250913-0015-plpgsql-tests.patch
- v20250913-0010-svariableReceiver.patch
- v20250913-0009-fill-an-auxiliary-buffer-with-values-of-session-vari.patch
- v20250913-0008-collect-session-variables-used-in-plan-and-assign-pa.patch
- v20250913-0007-local-HASHTAB-for-currently-used-session-variables-a.patch
- v20250913-0006-session-variable-fences-parsing.patch
- v20250913-0005-support-of-session-variables-for-pg_dump.patch
- v20250913-0004-support-of-session-variables-for-psql.patch
- v20250913-0003-GRANT-REVOKE-variable.patch
- v20250913-0001-introduce-new-class-catalog-pg_variable.patch
- v20250913-0002-CREATE-DROP-ALTER-VARIABLE.patch
Hi On 9/13/25 11:28, Pavel Stehule wrote: > > minor change (after private talk with Jim Jones) > After another pass, there are a few additional tests that should be included in this patch: == Additional tests for GRANT x ON VARIABLE == ============================================== We wanna make sure the proper error message is raised. postgres=# GRANT INSERT ON VARIABLE var TO jim; ERROR: invalid privilege type INSERT for session variable postgres=# GRANT DELETE ON VARIABLE var TO jim; ERROR: invalid privilege type DELETE for session variable == Tests for ALTER DEFAULT PRIVILEGES == ======================================== I couldn't find regression tests for ALTER DEFAULT PRIVILEGES ... if I haven't just missed them, I think they'd be a nice addition. postgres=# ALTER DEFAULT PRIVILEGES IN SCHEMA s GRANT UPDATE ON VARIABLES TO jim; ALTER DEFAULT PRIVILEGES postgres=# ALTER DEFAULT PRIVILEGES IN SCHEMA s GRANT INSERT ON VARIABLES TO jim; ERROR: invalid privilege type INSERT for session variable postgres=# ALTER DEFAULT PRIVILEGES IN SCHEMA s GRANT DELETE ON VARIABLES TO jim; ERROR: invalid privilege type DELETE for session variable postgres=# ALTER DEFAULT PRIVILEGES IN SCHEMA s GRANT SELECT ON VARIABLES TO jim; ALTER DEFAULT PRIVILEGES Best, Jim
Hi
po 15. 9. 2025 v 10:21 odesílatel Jim Jones <jim.jones@uni-muenster.de> napsal:
Hi
On 9/13/25 11:28, Pavel Stehule wrote:
>
> minor change (after private talk with Jim Jones)
>
After another pass, there are a few additional tests that should be
included in this patch:
== Additional tests for GRANT x ON VARIABLE ==
==============================================
We wanna make sure the proper error message is raised.
postgres=# GRANT INSERT ON VARIABLE var TO jim;
ERROR: invalid privilege type INSERT for session variable
postgres=# GRANT DELETE ON VARIABLE var TO jim;
ERROR: invalid privilege type DELETE for session variable
== Tests for ALTER DEFAULT PRIVILEGES ==
========================================
I couldn't find regression tests for ALTER DEFAULT PRIVILEGES ... if I
haven't just missed them, I think they'd be a nice addition.
postgres=# ALTER DEFAULT PRIVILEGES IN SCHEMA s GRANT UPDATE ON
VARIABLES TO jim;
ALTER DEFAULT PRIVILEGES
postgres=# ALTER DEFAULT PRIVILEGES IN SCHEMA s GRANT INSERT ON
VARIABLES TO jim;
ERROR: invalid privilege type INSERT for session variable
postgres=# ALTER DEFAULT PRIVILEGES IN SCHEMA s GRANT DELETE ON
VARIABLES TO jim;
ERROR: invalid privilege type DELETE for session variable
postgres=# ALTER DEFAULT PRIVILEGES IN SCHEMA s GRANT SELECT ON
VARIABLES TO jim;
ALTER DEFAULT PRIVILEGES
done
Regards
Pavel
Best, Jim
Вложения
- v20250915-0012-function-pg_get_session_variables_memory-for-cleanin.patch
- v20250915-0014-memory-cleaning-after-DROP-VARIABLE.patch
- v20250915-0011-LET-command-assign-a-result-of-expression-to-the-ses.patch
- v20250915-0015-plpgsql-tests.patch
- v20250915-0013-DISCARD-VARIABLES.patch
- v20250915-0009-fill-an-auxiliary-buffer-with-values-of-session-vari.patch
- v20250915-0010-svariableReceiver.patch
- v20250915-0008-collect-session-variables-used-in-plan-and-assign-pa.patch
- v20250915-0007-local-HASHTAB-for-currently-used-session-variables-a.patch
- v20250915-0006-session-variable-fences-parsing.patch
- v20250915-0005-support-of-session-variables-for-pg_dump.patch
- v20250915-0004-support-of-session-variables-for-psql.patch
- v20250915-0003-GRANT-REVOKE-variable.patch
- v20250915-0002-CREATE-DROP-ALTER-VARIABLE.patch
- v20250915-0001-introduce-new-class-catalog-pg_variable.patch
Hi
fresh rebase
Regards
Pavel
Вложения
- v20250929-0014-memory-cleaning-after-DROP-VARIABLE.patch
- v20250929-0012-function-pg_get_session_variables_memory-for-cleanin.patch
- v20250929-0015-plpgsql-tests.patch
- v20250929-0011-LET-command-assign-a-result-of-expression-to-the-ses.patch
- v20250929-0013-DISCARD-VARIABLES.patch
- v20250929-0010-svariableReceiver.patch
- v20250929-0009-fill-an-auxiliary-buffer-with-values-of-session-vari.patch
- v20250929-0008-collect-session-variables-used-in-plan-and-assign-pa.patch
- v20250929-0007-local-HASHTAB-for-currently-used-session-variables-a.patch
- v20250929-0006-session-variable-fences-parsing.patch
- v20250929-0005-support-of-session-variables-for-pg_dump.patch
- v20250929-0004-support-of-session-variables-for-psql.patch
- v20250929-0003-GRANT-REVOKE-variable.patch
- v20250929-0002-CREATE-DROP-ALTER-VARIABLE.patch
- v20250929-0001-introduce-new-class-catalog-pg_variable.patch