Thread: Enhancement to psql command, feedback.

Enhancement to psql command, feedback.

From
John McKown
Date:
I just wanted to throw this out to the users before I made a complete fool of myself by formally requesting it. But I would like what I hope would be a minor change (enhancement) to the psql command. If you look on this page, https://wiki.postgresql.org/wiki/Shared_Database_Hosting ,
you will see a number of example which look like:

psql -U postgres template1 -f - << EOT

REVOKE ALL ON DATABASE template1 FROM public;
REVOKE ALL ON SCHEMA public FROM public;
GRANT ALL ON SCHEMA public TO postgres;
CREATE LANGUAGE plpgsql;

EOT

To me this looks similar to a UNIX shell script. Now, going sideways for a second, if someone wanted to create a "self contained" awk script. It would look something like:

#!/bin/awk -f
... awk code ...

When a user executes the above from the command line, the UNIX system runs the program in the first "magic" line as if the user had entered "/bin/awk -f ..." where the ... is replaced by the name of the file executed followed by the rest of the command line parameters.

I think it would be nice if psql would do the same, mainly for "consistency" with other UNIX scripting languages, such as python, perl, & gawk.

The example above would then become:

#!/bin/psql -U postgres template1 -f
REVOKE ALL ON DATABASE template1 FROM public;
REVOKE ALL ON SCHEMA public FROM public;
GRANT ALL ON SCHEMA public TO postgres;
CREATE LANGUAGE plpgsql;
Does this seem reasonable to others? When I actually try the following as a "script", I get an error.

=== transcript ===

$ls -l ./x.psql; cat ./x.psql; ./x.psql
-rwxr-xr-x. 1 joarmc joarmc 40 May  9 02:55 ./x.psql
#!/usr/bin/psql -f
select * from table;
psql:./x.psql:2: ERROR:  syntax error at or near "#!/"
LINE 1: #!/usr/bin/psql -f
       ^


​I have not looked at the source yet, but it seems that it would be "easy" to implement if psql would simply ignore the first line of any file referenced via the "-f" parameter if it started with "#!" or maybe even just "#". I'm not suggesting ignoring _every_ line that start with that "magic", just the first.​


--
We all have skeletons in our closet.
Mine are so old, they have osteoporosis.

Maranatha! <><
John McKown

Re: Enhancement to psql command, feedback.

From
Pavel Stehule
Date:


2018-05-09 9:59 GMT+02:00 John McKown <john.archie.mckown@gmail.com>:
I just wanted to throw this out to the users before I made a complete fool of myself by formally requesting it. But I would like what I hope would be a minor change (enhancement) to the psql command. If you look on this page, https://wiki.postgresql.org/wiki/Shared_Database_Hosting ,
you will see a number of example which look like:

psql -U postgres template1 -f - << EOT

REVOKE ALL ON DATABASE template1 FROM public;
REVOKE ALL ON SCHEMA public FROM public;
GRANT ALL ON SCHEMA public TO postgres;
CREATE LANGUAGE plpgsql;

EOT

To me this looks similar to a UNIX shell script. Now, going sideways for a second, if someone wanted to create a "self contained" awk script. It would look something like:

#!/bin/awk -f
... awk code ...

When a user executes the above from the command line, the UNIX system runs the program in the first "magic" line as if the user had entered "/bin/awk -f ..." where the ... is replaced by the name of the file executed followed by the rest of the command line parameters.

I think it would be nice if psql would do the same, mainly for "consistency" with other UNIX scripting languages, such as python, perl, & gawk.

These languages has defined # as line comment. It is not true for SQL.

Regards

Pavel

 

The example above would then become:

#!/bin/psql -U postgres template1 -f
REVOKE ALL ON DATABASE template1 FROM public;
REVOKE ALL ON SCHEMA public FROM public;
GRANT ALL ON SCHEMA public TO postgres;
CREATE LANGUAGE plpgsql;
Does this seem reasonable to others? When I actually try the following as a "script", I get an error.

=== transcript ===

$ls -l ./x.psql; cat ./x.psql; ./x.psql
-rwxr-xr-x. 1 joarmc joarmc 40 May  9 02:55 ./x.psql
#!/usr/bin/psql -f
select * from table;
psql:./x.psql:2: ERROR:  syntax error at or near "#!/"
LINE 1: #!/usr/bin/psql -f
       ^


​I have not looked at the source yet, but it seems that it would be "easy" to implement if psql would simply ignore the first line of any file referenced via the "-f" parameter if it started with "#!" or maybe even just "#". I'm not suggesting ignoring _every_ line that start with that "magic", just the first.​


--
We all have skeletons in our closet.
Mine are so old, they have osteoporosis.

Maranatha! <><
John McKown

Re: Enhancement to psql command, feedback.

From
Matt Zagrabelny
Date:


On Wed, May 9, 2018 at 3:05 AM, Pavel Stehule <pavel.stehule@gmail.com> wrote:


2018-05-09 9:59 GMT+02:00 John McKown <john.archie.mckown@gmail.com>:
I just wanted to throw this out to the users before I made a complete fool of myself by formally requesting it. But I would like what I hope would be a minor change (enhancement) to the psql command. If you look on this page, https://wiki.postgresql.org/wiki/Shared_Database_Hosting ,
you will see a number of example which look like:

psql -U postgres template1 -f - << EOT

REVOKE ALL ON DATABASE template1 FROM public;
REVOKE ALL ON SCHEMA public FROM public;
GRANT ALL ON SCHEMA public TO postgres;
CREATE LANGUAGE plpgsql;

EOT

To me this looks similar to a UNIX shell script. Now, going sideways for a second, if someone wanted to create a "self contained" awk script. It would look something like:

#!/bin/awk -f
... awk code ...

When a user executes the above from the command line, the UNIX system runs the program in the first "magic" line as if the user had entered "/bin/awk -f ..." where the ... is replaced by the name of the file executed followed by the rest of the command line parameters.

I think it would be nice if psql would do the same, mainly for "consistency" with other UNIX scripting languages, such as python, perl, & gawk.

These languages has defined # as line comment. It is not true for SQL.

For fun, not because I've put considerable thought into it:

#!/usr/bin/psql --enable-hash-comment -f
...

-m

Re: Enhancement to psql command, feedback.

From
Ron
Date:
On 05/09/2018 02:59 AM, John McKown wrote:
I just wanted to throw this out to the users before I made a complete fool of myself by formally requesting it. But I would like what I hope would be a minor change (enhancement) to the psql command. If you look on this page, https://wiki.postgresql.org/wiki/Shared_Database_Hosting ,
you will see a number of example which look like:

psql -U postgres template1 -f - << EOT

REVOKE ALL ON DATABASE template1 FROM public;
REVOKE ALL ON SCHEMA public FROM public;
GRANT ALL ON SCHEMA public TO postgres;
CREATE LANGUAGE plpgsql;

EOT

To me this looks similar to a UNIX shell script.

Because it is a Unix shell script.  The "<< EOT" is part of a heredoc, which is designed to keep everything in one place instead of needing a second file for the SQL commands.

https://en.wikipedia.org/wiki/Here_document

(The concept is as old as computing.  Anyone who's worked on mainframes or proprietary minicomputers from DEC will instantly recognize it.)

--
Angular momentum makes the world go 'round.

Re: Enhancement to psql command, feedback.

From
John McKown
Date:
On Wed, May 9, 2018 at 3:05 AM, Pavel Stehule <pavel.stehule@gmail.com> wrote:


2018-05-09 9:59 GMT+02:00 John McKown <john.archie.mckown@gmail.com>:
I just wanted to throw this out to the users before I made a complete fool of myself by formally requesting it. But I would like what I hope would be a minor change (enhancement) to the psql command. If you look on this page, https://wiki.postgresql.org/wiki/Shared_Database_Hosting ,
you will see a number of example which look like:

psql -U postgres template1 -f - << EOT

REVOKE ALL ON DATABASE template1 FROM public;
REVOKE ALL ON SCHEMA public FROM public;
GRANT ALL ON SCHEMA public TO postgres;
CREATE LANGUAGE plpgsql;

EOT

To me this looks similar to a UNIX shell script. Now, going sideways for a second, if someone wanted to create a "self contained" awk script. It would look something like:

#!/bin/awk -f
... awk code ...

When a user executes the above from the command line, the UNIX system runs the program in the first "magic" line as if the user had entered "/bin/awk -f ..." where the ... is replaced by the name of the file executed followed by the rest of the command line parameters.

I think it would be nice if psql would do the same, mainly for "consistency" with other UNIX scripting languages, such as python, perl, & gawk.

These languages has defined # as line comment. It is not true for SQL.

​Thanks, that looks like a "NO" vote to me. ​

 

Regards

Pavel



--
We all have skeletons in our closet.
Mine are so old, they have osteoporosis.

Maranatha! <><
John McKown

Re: Enhancement to psql command, feedback.

From
John McKown
Date:
On Wed, May 9, 2018 at 8:17 AM, Ron <ronljohnsonjr@gmail.com> wrote:
On 05/09/2018 02:59 AM, John McKown wrote:
I just wanted to throw this out to the users before I made a complete fool of myself by formally requesting it. But I would like what I hope would be a minor change (enhancement) to the psql command. If you look on this page, https://wiki.postgresql.org/wiki/Shared_Database_Hosting ,
you will see a number of example which look like:

psql -U postgres template1 -f - << EOT

REVOKE ALL ON DATABASE template1 FROM public;
REVOKE ALL ON SCHEMA public FROM public;
GRANT ALL ON SCHEMA public TO postgres;
CREATE LANGUAGE plpgsql;

EOT

To me this looks similar to a UNIX shell script.

Because it is a Unix shell script.  The "<< EOT" is part of a heredoc, which is designed to keep everything in one place instead of needing a second file for the SQL commands.

https://en.wikipedia.org/wiki/Here_document

(The concept is as old as computing.  Anyone who's worked on mainframes or proprietary minicomputers from DEC will instantly recognize it.)

​Yes, I use HERE docs in my shell scripts. I was just, sort of, wanting to avoid that by making a "slight" change to the psql program to ignore the first (and only the first) line of any file referenced​ via a "-f". This is NOT any kind of critical necessity. I just think it would be "nice" simply because _I_ have a habit of use the "magic" #! at the start of the first like in order to have other "languages" (such as python, perl, gawk), be invoked with the script file name as a parameter. One reason to avoid a HERE doc is from what I've learned about how BASH at least implements them. The BASH shell sees the HERE document and copies it into a "temporary" disk file. It then opens this file and supplies that file descriptor to whatever is being fed the HERE document as input. So, in effect, using a HERE document, at least in BASH, does a lot more I/O to the disk system. 

Again, this is just a discussion point. And I'm quite willing to admit defeat if most people don't think that it is worth the effort.

 


--
Angular momentum makes the world go 'round.



--
We all have skeletons in our closet.
Mine are so old, they have osteoporosis.

Maranatha! <><
John McKown

Re: Enhancement to psql command, feedback.

From
Stephen Frost
Date:
Greetings,

* John McKown (john.archie.mckown@gmail.com) wrote:
> Again, this is just a discussion point. And I'm quite willing to admit
> defeat if most people don't think that it is worth the effort.

For my 2c, at least, I do think it'd be kind of neat to have, but we'd
need a fool-proof way to realize that's how we're being called and,
ideally, that would be something we could detect without having to have
special flags for psql which anyone writing such a script would have to
be aware of.

Do you know if there's a way to detect that we're being called this
way..?

Thanks!

Stephen

Attachment

Re: Enhancement to psql command, feedback.

From
"David G. Johnston"
Date:
On Wed, May 9, 2018 at 6:44 AM, John McKown <john.archie.mckown@gmail.com> wrote:
Again, this is just a discussion point. And I'm quite willing to admit defeat if most people don't think that it is worth the effort.

​-1, at least per the example.  I would not want "-U postgres" inside the file.  I tend to rely on service entries, not environment variables, and wouldn't want to hard-code them either.  While psql has grown more flow-control capabilities recently it is, in most cases, a support language for me, not a main entry point.  Shell scripts merge the per-instance run-time environment I need with the behavior the script provides - merging that I find I need more often than not and don't miss the added overhead in the few cases where it is unnecessary.

David J.

Re: Enhancement to psql command, feedback.

From
John McKown
Date:
On Wed, May 9, 2018 at 8:56 AM, David G. Johnston <david.g.johnston@gmail.com> wrote:
On Wed, May 9, 2018 at 6:44 AM, John McKown <john.archie.mckown@gmail.com> wrote:
Again, this is just a discussion point. And I'm quite willing to admit defeat if most people don't think that it is worth the effort.

​-1, at least per the example.  I would not want "-U postgres" inside the file.  I tend to rely on service entries, not environment variables, and wouldn't want to hard-code them either.  While psql has grown more flow-control capabilities recently it is, in most cases, a support language for me, not a main entry point.  Shell scripts merge the per-instance run-time environment I need with the behavior the script provides - merging that I find I need more often than not and don't miss the added overhead in the few cases where it is unnecessary.

David J.


​I agree. I wouldn't want the -U inside a "regular" shell script either. As a minor example, consider the following _almost_ equivalent scripts.


$ cat psql-script.sh
#!/bin/sh
psql "$@" -f - <<EOT
select * from table;
EOF

$ cat psql-script.sql
#!/usr/bin/psql -f -
select * from table


$ chmod 755 psql-script.{sh,sql}
$ ./psql-script.sh -U postgres -d somedb -h remote-host.com 
$ ./psql-script.sql -U postgres -d somedb -h remote-host.com

​​


​These are _almost_ equivalent.​ The first execution shown after the chmod is effectively:

psql -U postgres -d somedb -h remote-host.com -f - <<EOT
select * from table;
EOT

​The second is effectively:

/usr/bin/psql  -f ./psql-script.sql -U postgres -d somedb -h remote-host.com

The only difference is whether the -f is "at the front" or "at the end" of the "generated" command which is actually sent to the exec() function. In reality, from what the BASH maintainer has said, the first script is a bit like:

file=$(mktemp) # generate a temporary file name
{ cat <<EOT
select * from table;
EOT
} >${file}
psql -U postgres -d somedb -h remote-host.com -f ${file}

It just that the HERE document doesn't actually create the ${file} variable. I have NO idea how other shell implement HERE documents.

However, in the second case, the "magic" first line causes psql, at present, to report an error and abort. This is why I'd like to modify how the file referenced via the -f argument is processed. That is, the first line of any file referenced & executed via the -f argument will be ignored if and only if it starts with a shebang (#!). If the first line of the file does not start with a shebang, it is processed normally as are all subsequent lines.

If I get the energy & time, I'll give a look at the actual source. If it is within my, admitted limited, ability to generate a patch to implement what I'm thinking of, I'll post it over on the development forum.


--
We all have skeletons in our closet.
Mine are so old, they have osteoporosis.

Maranatha! <><
John McKown

Re: Enhancement to psql command, feedback.

From
John McKown
Date:
On Wed, May 9, 2018 at 8:52 AM, Stephen Frost <sfrost@snowman.net> wrote:
Greetings,

* John McKown (john.archie.mckown@gmail.com) wrote:
> Again, this is just a discussion point. And I'm quite willing to admit
> defeat if most people don't think that it is worth the effort.

For my 2c, at least, I do think it'd be kind of neat to have, but we'd
need a fool-proof way to realize that's how we're being called and,
ideally, that would be something we could detect without having to have
special flags for psql which anyone writing such a script would have to
be aware of.

​I probably should have taken a good look at how the psql code actually handles the "-f" argument. Unfortunately, I've been very "time poor​" recently due to some medical work which, along with "real" work, keeps me away from the house for about 15 hrs a day, except for weekends which I used to try to recover.

 

Do you know if there's a way to detect that we're being called this
way..?

Thanks!

Stephen



--
We all have skeletons in our closet.
Mine are so old, they have osteoporosis.

Maranatha! <><
John McKown

Re: Enhancement to psql command, feedback.

From
"David G. Johnston"
Date:
On Wed, May 9, 2018 at 7:17 AM, John McKown <john.archie.mckown@gmail.com> wrote:

However, in the second case, the "magic" first line causes psql, at present, to report an error and abort. This is why I'd like to modify how the file referenced via the -f argument is processed. That is, the first line of any file referenced & executed via the -f argument will be ignored if and only if it starts with a shebang (#!). If the first line of the file does not start with a shebang, it is processed normally as are all subsequent lines.


​Don't forget the \i and \ir meta commands.

David J.

Re: Enhancement to psql command, feedback.

From
Tom Lane
Date:
Stephen Frost <sfrost@snowman.net> writes:
> Greetings,
> * John McKown (john.archie.mckown@gmail.com) wrote:
>> Again, this is just a discussion point. And I'm quite willing to admit
>> defeat if most people don't think that it is worth the effort.

> For my 2c, at least, I do think it'd be kind of neat to have, but we'd
> need a fool-proof way to realize that's how we're being called and,
> ideally, that would be something we could detect without having to have
> special flags for psql which anyone writing such a script would have to
> be aware of.
> Do you know if there's a way to detect that we're being called this
> way..?

Actually, I'd say that's exactly what *not* to do.  It's generally
important that a script act the same whether or not it was invoked
with a shortcut.  For instance, just because you had one of these
magic lines at the top, you'd not want it to not work if called
via \include.

So my take on it is that this is a request to ignore the first line
if it starts with "#!" (and yes, I'd insist on checking both characters).
I do not see that as noticeably more dangerous than the existing kluge
to ignore a UTF BOM character at the start of the file.

The concerns about whether psql would get invoked with a desirable
set of options if you tried to do this seem more worrisome, but if
that does work out usefully, I think this is a reasonable proposal.

            regards, tom lane


Re: Enhancement to psql command, feedback.

From
Christopher Browne
Date:
On Wed, 9 May 2018 at 04:00, John McKown <john.archie.mckown@gmail.com>
wrote:
> To me this looks similar to a UNIX shell script. Now, going sideways for
a second, if someone wanted to create a "self contained" awk script. It
would look something like:

> #!/bin/awk -f
> ... awk code ...

I have found it convenient when Lisp implementations (that use ; as the
comment indicator, and where # tends to mean something quite different)
have provided something like this.

I'd quite like it if I could start a script with
#!psql
or similar and have it be, yes, indeed, directly executable via psql.

There are several complications that leap out at me...

1.  Would want to run the apropos psql

It's a common thing in Perl to have an idiom where a suitable script prefix
goes off and finds the appropriate Perl instance.  It's possible to have
multiple versions of psql, it would be kinda nice if the script could
choose the right one to run.  But that could easily be trying too hard.

2.  Specifying database connection parameters

Making use of PGDATABASE and other environment parameters is well and good;
it would also be a fine thing for something in the first line to be able to
specify values.

Thus, something like...

#!psql -d postgresql://postgres@localhost:5432/some_db_name

The not-so-nice is that perhaps that first line provides some defaults, and
one could override slices of that via PGDATABASE/PGHOST/PGUSER/...

What overrides what is an excellent question, and perhaps a horrible
bikeshedding debate.

3.  Nesting is a funny thing; I'm not sure if \i should simply ignore the
first line if it begins with #!, or if it should become a "subshell"
perhaps in another psql session.

In effect, is \i like a C #include (ergo, perhaps strip leading line
beginning with #!), or is it a separate psql session, with separate
connection/transaction?  I imagine it's more like #include, but
both seem potentially useful.

There's certainly a danger of bikeshedding.
-- 
When confronted by a difficult problem, solve it by reducing it to the
question, "How would the Lone Ranger handle this?"


Re: Enhancement to psql command, feedback.

From
"David G. Johnston"
Date:
On Wed, May 9, 2018 at 9:04 AM, Christopher Browne <cbbrowne@gmail.com> wrote:
On Wed, 9 May 2018 at 04:00, John McKown <john.archie.mckown@gmail.com>
wrote:
> To me this looks similar to a UNIX shell script. Now, going sideways for
a second, if someone wanted to create a "self contained" awk script. It
would look something like:

> #!/bin/awk -f
> ... awk code ...

I have found it convenient when Lisp implementations (that use ; as the
comment indicator, and where # tends to mean something quite different)
have provided something like this.

I'd quite like it if I could start a script with
#!psql
or similar and have it be, yes, indeed, directly executable via psql.

There are several complications that leap out at me...

​Frankly, none of those are complications.  For all the areas of concern you described the decision for desired behavior has already been made.  They seem to limit the extent to which a shebang would be useful...

1. O/S PATH determines what a bare "psql" invocation finds
2. arguments override environment variables
3. \i means include, no transaction semantics

And trying harder for #1 doesn't seem worthwhile - or maybe is a feature in its own right.  Something like:

--@ client-version >= 9.6
--@ server-version >= 9.4

If those comments are found in a file psql is evaluating it should error out if the condition doesn't match.  That should apply regardless of invocation method.

David J.

Re: Enhancement to psql command, feedback.

From
Jan Claeys
Date:
On Wed, 2018-05-09 at 08:36 -0500, John McKown wrote:
> On Wed, May 9, 2018 at 3:05 AM, Pavel Stehule
> <pavel.stehule@gmail.com> wrote:

> > These languages has defined # as line comment. It is not true for
> > SQL.
> 
> Thanks, that looks like a "NO" vote to me. 
> 


Not necessarily. There are other languages which don't use "#" for
comments, but ignore a first line when it starts with "#" or when you
add a specific command line option.


-- 
Jan Claeys


Re: Enhancement to psql command, feedback.

From
Steven Lembark
Date:
The whole point of "#!" working in shell is that the two-bytes
(a) mark the file as executable by a specific shell command and 
(b) are a shell comment.

One fairly simple fix that would make annotating here scripts
and the like simpler for shell(ish) execution would be simply
ignoring all text from "\n#" to the first "\n", which would 
allow the #! to function as a comment -- just as it does in
the shell. 

Another way to do it would be adding a '#' command to psql,
similar to '\', that accepts a one-line directive and ignores
it entirely. This would use the existing framework for detecting
the context of '\' as a command, just with a different magic
char.


-- 
Steven Lembark                                       1505 National Ave
Workhorse Computing                                 Rockford, IL 61103
lembark@wrkhors.com                                    +1 888 359 3508


Re: Enhancement to psql command, feedback.

From
Francisco Olarte
Date:
On Thu, May 10, 2018 at 4:46 PM, Steven Lembark <lembark@wrkhors.com> wrote:
> The whole point of "#!" working in shell is that the two-bytes
> (a) mark the file as executable by a specific shell command and
> (b) are a shell comment.

Shebang is an unix-ism. It is not part of the shell. The shell just
execs whatever you tell it to.

In a simple way, in unix when a file is marked executable the loader
is called to load and execute it. The loader first looks at the start
of the file to try to determine what it is ( it does not use the
'extension' for this as MSDOS and friends ). If it is one of the
several formats binary formats, like elf or a.out, it understands it
loads and executes. If it is the magic sequence "#!" it tries to
search for another executable ( NOT A SHELL COMMAND, this works even
if you zap all the shells in your computer ) and recursively invokes
it ( this is done by execve(2) in my linux machine, and described in
its manual page ).

No shell involved:

folarte:~/tmp$ type cat
cat is /bin/cat
folarte:~/tmp$ echo -e '#!/bin/cat\nHello there\nGood bye then' > xx
folarte:~/tmp$ chmod +x xx
folarte:~/tmp$ ./xx
#!/bin/cat
Hello there
Good bye then
folarte:~/tmp$ perl -e 'exec("./xx")'
#!/bin/cat
Hello there
Good bye then

You can try other ways to call execv*, nothing magical in the perl
way, just avoiding the shell ( which has an exec builtin command, with
different behaviour from typing a command name, which does fork, wait
in the parent, execv in the child ).

Francisco Olarte.