2013-02-02 23:06:38 +01:00
|
|
|
--
|
|
|
|
-- Tests for psql features that aren't closely connected to any
|
|
|
|
-- specific server features
|
|
|
|
--
|
|
|
|
|
Make psql reject attempts to set special variables to invalid values.
Previously, if the user set a special variable such as ECHO to an
unrecognized value, psql would bleat but store the new value anyway, and
then fall back to a default setting for the behavior controlled by the
variable. This was agreed to be a not particularly good idea. With
this patch, invalid values result in an error message and no change in
state.
(But this applies only to variables that affect psql's behavior; purely
informational variables such as ENCODING can still be set to random
values.)
To do this, modify the API for psql's assign-hook functions so that they
can return an OK/not OK result, and give them the responsibility for
printing error messages when they reject a value. Adjust the APIs for
ParseVariableBool and ParseVariableNum to support the new behavior
conveniently.
In passing, document the variable VERSION, which had somehow escaped that.
And improve the quite-inadequate commenting in psql/variables.c.
Daniel Vérité, reviewed by Rahila Syed, some further tweaking by me
Discussion: https://postgr.es/m/7356e741-fa59-4146-a8eb-cf95fd6b21fb@mm
2017-01-30 22:37:15 +01:00
|
|
|
-- \set
|
|
|
|
|
|
|
|
-- fail: invalid name
|
|
|
|
\set invalid/name foo
|
|
|
|
-- fail: invalid value for special variable
|
|
|
|
\set AUTOCOMMIT foo
|
|
|
|
\set FETCH_COUNT foo
|
Improve psql's behavior for \set and \unset of its control variables.
This commit improves on the results of commit 511ae628f in two ways:
1. It restores the historical behavior that "\set FOO" is interpreted
as setting FOO to "on", if FOO is a boolean control variable. We
already found one test script that was expecting that behavior, and
the psql documentation certainly does nothing to discourage people
from assuming that would work, since it often says just "if FOO is set"
when describing the effects of a boolean variable. However, now this
case will result in actually setting FOO to "on", not an empty string.
2. It arranges for an "\unset" of a control variable to set the value
back to its default value, rather than becoming apparently undefined.
The control variables are also initialized that way at psql startup.
In combination, these things guarantee that a control variable always
has a displayable value that reflects what psql is actually doing.
That is a pretty substantial usability improvement.
The implementation involves adding a second type of variable hook function
that is able to replace a proposed new value (including NULL) with another
one. We could alternatively have complicated the API of the assign hook,
but this way seems better since many variables can share the same
substitution hook function.
Also document the actual behavior of these variables more fully,
including covering assorted behaviors that were there before but
never documented.
This patch also includes some minor cleanup that should have been in
511ae628f but was missed.
Patch by me, but it owes a lot to discussions with Daniel Vérité.
Discussion: https://postgr.es/m/9572.1485821620@sss.pgh.pa.us
2017-02-01 17:02:40 +01:00
|
|
|
-- check handling of built-in boolean variable
|
|
|
|
\echo :ON_ERROR_ROLLBACK
|
|
|
|
\set ON_ERROR_ROLLBACK
|
|
|
|
\echo :ON_ERROR_ROLLBACK
|
|
|
|
\set ON_ERROR_ROLLBACK foo
|
|
|
|
\echo :ON_ERROR_ROLLBACK
|
|
|
|
\set ON_ERROR_ROLLBACK on
|
|
|
|
\echo :ON_ERROR_ROLLBACK
|
|
|
|
\unset ON_ERROR_ROLLBACK
|
|
|
|
\echo :ON_ERROR_ROLLBACK
|
Make psql reject attempts to set special variables to invalid values.
Previously, if the user set a special variable such as ECHO to an
unrecognized value, psql would bleat but store the new value anyway, and
then fall back to a default setting for the behavior controlled by the
variable. This was agreed to be a not particularly good idea. With
this patch, invalid values result in an error message and no change in
state.
(But this applies only to variables that affect psql's behavior; purely
informational variables such as ENCODING can still be set to random
values.)
To do this, modify the API for psql's assign-hook functions so that they
can return an OK/not OK result, and give them the responsibility for
printing error messages when they reject a value. Adjust the APIs for
ParseVariableBool and ParseVariableNum to support the new behavior
conveniently.
In passing, document the variable VERSION, which had somehow escaped that.
And improve the quite-inadequate commenting in psql/variables.c.
Daniel Vérité, reviewed by Rahila Syed, some further tweaking by me
Discussion: https://postgr.es/m/7356e741-fa59-4146-a8eb-cf95fd6b21fb@mm
2017-01-30 22:37:15 +01:00
|
|
|
|
2013-02-02 23:06:38 +01:00
|
|
|
-- \gset
|
|
|
|
|
|
|
|
select 10 as test01, 20 as test02, 'Hello' as test03 \gset pref01_
|
|
|
|
|
|
|
|
\echo :pref01_test01 :pref01_test02 :pref01_test03
|
|
|
|
|
|
|
|
-- should fail: bad variable name
|
|
|
|
select 10 as "bad name"
|
|
|
|
\gset
|
|
|
|
|
|
|
|
-- multiple backslash commands in one line
|
|
|
|
select 1 as x, 2 as y \gset pref01_ \\ \echo :pref01_x
|
|
|
|
select 3 as x, 4 as y \gset pref01_ \echo :pref01_x \echo :pref01_y
|
|
|
|
select 5 as x, 6 as y \gset pref01_ \\ \g \echo :pref01_x :pref01_y
|
|
|
|
select 7 as x, 8 as y \g \gset pref01_ \echo :pref01_x :pref01_y
|
|
|
|
|
|
|
|
-- NULL should unset the variable
|
|
|
|
\set var2 xyz
|
|
|
|
select 1 as var1, NULL as var2, 3 as var3 \gset
|
|
|
|
\echo :var1 :var2 :var3
|
|
|
|
|
|
|
|
-- \gset requires just one tuple
|
|
|
|
select 10 as test01, 20 as test02 from generate_series(1,3) \gset
|
|
|
|
select 10 as test01, 20 as test02 from generate_series(1,0) \gset
|
|
|
|
|
|
|
|
-- \gset should work in FETCH_COUNT mode too
|
|
|
|
\set FETCH_COUNT 1
|
|
|
|
|
|
|
|
select 1 as x, 2 as y \gset pref01_ \\ \echo :pref01_x
|
|
|
|
select 3 as x, 4 as y \gset pref01_ \echo :pref01_x \echo :pref01_y
|
|
|
|
select 10 as test01, 20 as test02 from generate_series(1,3) \gset
|
|
|
|
select 10 as test01, 20 as test02 from generate_series(1,0) \gset
|
|
|
|
|
|
|
|
\unset FETCH_COUNT
|
2013-10-03 21:18:02 +02:00
|
|
|
|
Add a \gexec command to psql for evaluation of computed queries.
\gexec executes the just-entered query, like \g, but instead of printing
the results it takes each field as a SQL command to send to the server.
Computing a series of queries to be executed is a fairly common thing,
but up to now you always had to resort to kluges like writing the queries
to a file and then inputting the file. Now it can be done with no
intermediate step.
The implementation is fairly straightforward except for its interaction
with FETCH_COUNT. ExecQueryUsingCursor isn't capable of being called
recursively, and even if it were, its need to create a transaction
block interferes unpleasantly with the desired behavior of \gexec after
a failure of a generated query (i.e., that it can continue). Therefore,
disable use of ExecQueryUsingCursor when doing the master \gexec query.
We can still apply it to individual generated queries, however, and there
might be some value in doing so.
While testing this feature's interaction with single-step mode, I (tgl) was
led to conclude that SendQuery needs to recognize SIGINT (cancel_pressed)
as a negative response to the single-step prompt. Perhaps that's a
back-patchable bug fix, but for now I just included it here.
Corey Huinker, reviewed by Jim Nasby, Daniel Vérité, and myself
2016-04-04 21:25:16 +02:00
|
|
|
-- \gexec
|
|
|
|
|
|
|
|
create temporary table gexec_test(a int, b text, c date, d float);
|
|
|
|
select format('create index on gexec_test(%I)', attname)
|
|
|
|
from pg_attribute
|
|
|
|
where attrelid = 'gexec_test'::regclass and attnum > 0
|
|
|
|
order by attnum
|
|
|
|
\gexec
|
|
|
|
|
|
|
|
-- \gexec should work in FETCH_COUNT mode too
|
|
|
|
-- (though the fetch limit applies to the executed queries not the meta query)
|
|
|
|
\set FETCH_COUNT 1
|
|
|
|
|
|
|
|
select 'select 1 as ones', 'select x.y, x.y*2 as double from generate_series(1,4) as x(y)'
|
|
|
|
union all
|
|
|
|
select 'drop table gexec_test', NULL
|
|
|
|
union all
|
|
|
|
select 'drop table gexec_test', 'select ''2000-01-01''::date as party_over'
|
|
|
|
\gexec
|
|
|
|
|
|
|
|
\unset FETCH_COUNT
|
|
|
|
|
2013-10-03 21:18:02 +02:00
|
|
|
-- show all pset options
|
|
|
|
\pset
|
2014-04-28 19:41:36 +02:00
|
|
|
|
|
|
|
-- test multi-line headers, wrapping, and newline indicators
|
2014-08-18 13:06:11 +02:00
|
|
|
prepare q as select array_to_string(array_agg(repeat('x',2*n)),E'\n') as "ab
|
2014-04-28 19:41:36 +02:00
|
|
|
|
2014-08-18 13:06:11 +02:00
|
|
|
c", array_to_string(array_agg(repeat('y',20-2*n)),E'\n') as "a
|
2016-10-10 22:41:57 +02:00
|
|
|
bc" from generate_series(1,10) as n(n) group by n>1 order by n>1;
|
2014-04-28 19:41:36 +02:00
|
|
|
|
|
|
|
\pset linestyle ascii
|
|
|
|
|
|
|
|
\pset expanded off
|
|
|
|
\pset columns 40
|
|
|
|
|
|
|
|
\pset border 0
|
|
|
|
\pset format unaligned
|
|
|
|
execute q;
|
|
|
|
\pset format aligned
|
|
|
|
execute q;
|
|
|
|
\pset format wrapped
|
|
|
|
execute q;
|
|
|
|
|
|
|
|
\pset border 1
|
|
|
|
\pset format unaligned
|
|
|
|
execute q;
|
|
|
|
\pset format aligned
|
|
|
|
execute q;
|
|
|
|
\pset format wrapped
|
|
|
|
execute q;
|
|
|
|
|
|
|
|
\pset border 2
|
|
|
|
\pset format unaligned
|
|
|
|
execute q;
|
|
|
|
\pset format aligned
|
|
|
|
execute q;
|
|
|
|
\pset format wrapped
|
|
|
|
execute q;
|
|
|
|
|
|
|
|
\pset expanded on
|
|
|
|
\pset columns 20
|
|
|
|
|
|
|
|
\pset border 0
|
|
|
|
\pset format unaligned
|
|
|
|
execute q;
|
|
|
|
\pset format aligned
|
|
|
|
execute q;
|
|
|
|
\pset format wrapped
|
|
|
|
execute q;
|
|
|
|
|
|
|
|
\pset border 1
|
|
|
|
\pset format unaligned
|
|
|
|
execute q;
|
|
|
|
\pset format aligned
|
|
|
|
execute q;
|
|
|
|
\pset format wrapped
|
|
|
|
execute q;
|
|
|
|
|
|
|
|
\pset border 2
|
|
|
|
\pset format unaligned
|
|
|
|
execute q;
|
|
|
|
\pset format aligned
|
|
|
|
execute q;
|
|
|
|
\pset format wrapped
|
|
|
|
execute q;
|
|
|
|
|
|
|
|
\pset linestyle old-ascii
|
|
|
|
|
|
|
|
\pset expanded off
|
|
|
|
\pset columns 40
|
|
|
|
|
|
|
|
\pset border 0
|
|
|
|
\pset format unaligned
|
|
|
|
execute q;
|
|
|
|
\pset format aligned
|
|
|
|
execute q;
|
|
|
|
\pset format wrapped
|
|
|
|
execute q;
|
|
|
|
|
|
|
|
\pset border 1
|
|
|
|
\pset format unaligned
|
|
|
|
execute q;
|
|
|
|
\pset format aligned
|
|
|
|
execute q;
|
|
|
|
\pset format wrapped
|
|
|
|
execute q;
|
|
|
|
|
|
|
|
\pset border 2
|
|
|
|
\pset format unaligned
|
|
|
|
execute q;
|
|
|
|
\pset format aligned
|
|
|
|
execute q;
|
|
|
|
\pset format wrapped
|
|
|
|
execute q;
|
|
|
|
|
|
|
|
\pset expanded on
|
|
|
|
\pset columns 20
|
|
|
|
|
|
|
|
\pset border 0
|
|
|
|
\pset format unaligned
|
|
|
|
execute q;
|
|
|
|
\pset format aligned
|
|
|
|
execute q;
|
|
|
|
\pset format wrapped
|
|
|
|
execute q;
|
|
|
|
|
|
|
|
\pset border 1
|
|
|
|
\pset format unaligned
|
|
|
|
execute q;
|
|
|
|
\pset format aligned
|
|
|
|
execute q;
|
|
|
|
\pset format wrapped
|
|
|
|
execute q;
|
|
|
|
|
|
|
|
\pset border 2
|
|
|
|
\pset format unaligned
|
|
|
|
execute q;
|
|
|
|
\pset format aligned
|
|
|
|
execute q;
|
|
|
|
\pset format wrapped
|
|
|
|
execute q;
|
|
|
|
|
|
|
|
deallocate q;
|
2014-08-18 13:06:11 +02:00
|
|
|
|
|
|
|
-- test single-line header and data
|
|
|
|
prepare q as select repeat('x',2*n) as "0123456789abcdef", repeat('y',20-2*n) as "0123456789" from generate_series(1,10) as n;
|
|
|
|
|
|
|
|
\pset linestyle ascii
|
|
|
|
|
|
|
|
\pset expanded off
|
|
|
|
\pset columns 40
|
|
|
|
|
|
|
|
\pset border 0
|
|
|
|
\pset format unaligned
|
|
|
|
execute q;
|
|
|
|
\pset format aligned
|
|
|
|
execute q;
|
|
|
|
\pset format wrapped
|
|
|
|
execute q;
|
|
|
|
|
|
|
|
\pset border 1
|
|
|
|
\pset format unaligned
|
|
|
|
execute q;
|
|
|
|
\pset format aligned
|
2015-11-30 23:53:32 +01:00
|
|
|
execute q;
|
|
|
|
\pset format wrapped
|
|
|
|
execute q;
|
|
|
|
|
|
|
|
\pset border 2
|
|
|
|
\pset format unaligned
|
|
|
|
execute q;
|
|
|
|
\pset format aligned
|
|
|
|
execute q;
|
|
|
|
\pset format wrapped
|
|
|
|
execute q;
|
|
|
|
|
|
|
|
\pset expanded on
|
|
|
|
\pset columns 30
|
|
|
|
|
|
|
|
\pset border 0
|
|
|
|
\pset format unaligned
|
|
|
|
execute q;
|
|
|
|
\pset format aligned
|
|
|
|
execute q;
|
|
|
|
\pset format wrapped
|
|
|
|
execute q;
|
|
|
|
|
|
|
|
\pset border 1
|
|
|
|
\pset format unaligned
|
|
|
|
execute q;
|
|
|
|
\pset format aligned
|
2014-08-18 13:06:11 +02:00
|
|
|
execute q;
|
|
|
|
\pset format wrapped
|
|
|
|
execute q;
|
|
|
|
|
|
|
|
\pset border 2
|
|
|
|
\pset format unaligned
|
|
|
|
execute q;
|
|
|
|
\pset format aligned
|
|
|
|
execute q;
|
|
|
|
\pset format wrapped
|
|
|
|
execute q;
|
|
|
|
|
|
|
|
\pset expanded on
|
|
|
|
\pset columns 20
|
|
|
|
|
|
|
|
\pset border 0
|
|
|
|
\pset format unaligned
|
|
|
|
execute q;
|
|
|
|
\pset format aligned
|
|
|
|
execute q;
|
|
|
|
\pset format wrapped
|
|
|
|
execute q;
|
|
|
|
|
|
|
|
\pset border 1
|
|
|
|
\pset format unaligned
|
|
|
|
execute q;
|
|
|
|
\pset format aligned
|
|
|
|
execute q;
|
|
|
|
\pset format wrapped
|
|
|
|
execute q;
|
|
|
|
|
|
|
|
\pset border 2
|
|
|
|
\pset format unaligned
|
|
|
|
execute q;
|
|
|
|
\pset format aligned
|
|
|
|
execute q;
|
|
|
|
\pset format wrapped
|
|
|
|
execute q;
|
|
|
|
|
|
|
|
\pset linestyle old-ascii
|
|
|
|
|
|
|
|
\pset expanded off
|
|
|
|
\pset columns 40
|
|
|
|
|
|
|
|
\pset border 0
|
|
|
|
\pset format unaligned
|
|
|
|
execute q;
|
|
|
|
\pset format aligned
|
|
|
|
execute q;
|
|
|
|
\pset format wrapped
|
|
|
|
execute q;
|
|
|
|
|
|
|
|
\pset border 1
|
|
|
|
\pset format unaligned
|
|
|
|
execute q;
|
|
|
|
\pset format aligned
|
|
|
|
execute q;
|
|
|
|
\pset format wrapped
|
|
|
|
execute q;
|
|
|
|
|
|
|
|
\pset border 2
|
|
|
|
\pset format unaligned
|
|
|
|
execute q;
|
|
|
|
\pset format aligned
|
|
|
|
execute q;
|
|
|
|
\pset format wrapped
|
|
|
|
execute q;
|
|
|
|
|
|
|
|
\pset expanded on
|
|
|
|
|
|
|
|
\pset border 0
|
|
|
|
\pset format unaligned
|
|
|
|
execute q;
|
|
|
|
\pset format aligned
|
|
|
|
execute q;
|
|
|
|
\pset format wrapped
|
|
|
|
execute q;
|
|
|
|
|
|
|
|
\pset border 1
|
|
|
|
\pset format unaligned
|
|
|
|
execute q;
|
|
|
|
\pset format aligned
|
|
|
|
execute q;
|
|
|
|
\pset format wrapped
|
|
|
|
execute q;
|
|
|
|
|
|
|
|
\pset border 2
|
|
|
|
\pset format unaligned
|
|
|
|
execute q;
|
|
|
|
\pset format aligned
|
|
|
|
execute q;
|
|
|
|
\pset format wrapped
|
|
|
|
execute q;
|
|
|
|
|
|
|
|
deallocate q;
|
2015-03-31 17:33:25 +02:00
|
|
|
|
2016-04-09 01:23:18 +02:00
|
|
|
\pset linestyle ascii
|
|
|
|
|
2015-03-31 17:33:25 +02:00
|
|
|
prepare q as select ' | = | lkjsafi\\/ /oeu rio)(!@&*#)*(!&@*) \ (&' as " | -- | 012345678 9abc def!*@#&!@(*&*~~_+-=\ \", '11' as "0123456789", 11 as int from generate_series(1,10) as n;
|
|
|
|
|
|
|
|
\pset format asciidoc
|
|
|
|
\pset expanded off
|
|
|
|
\pset border 0
|
|
|
|
execute q;
|
|
|
|
|
|
|
|
\pset border 1
|
|
|
|
execute q;
|
|
|
|
|
|
|
|
\pset border 2
|
|
|
|
execute q;
|
|
|
|
|
|
|
|
\pset expanded on
|
|
|
|
\pset border 0
|
|
|
|
execute q;
|
|
|
|
|
|
|
|
\pset border 1
|
|
|
|
execute q;
|
|
|
|
|
|
|
|
\pset border 2
|
|
|
|
execute q;
|
|
|
|
|
|
|
|
deallocate q;
|
2015-09-05 17:58:20 +02:00
|
|
|
|
2016-04-09 01:23:18 +02:00
|
|
|
\pset format aligned
|
|
|
|
\pset expanded off
|
|
|
|
\pset border 1
|
|
|
|
|
2015-09-05 17:58:20 +02:00
|
|
|
-- SHOW_CONTEXT
|
|
|
|
|
|
|
|
\set SHOW_CONTEXT never
|
|
|
|
do $$
|
|
|
|
begin
|
|
|
|
raise notice 'foo';
|
|
|
|
raise exception 'bar';
|
|
|
|
end $$;
|
|
|
|
|
|
|
|
\set SHOW_CONTEXT errors
|
|
|
|
do $$
|
|
|
|
begin
|
|
|
|
raise notice 'foo';
|
|
|
|
raise exception 'bar';
|
|
|
|
end $$;
|
|
|
|
|
|
|
|
\set SHOW_CONTEXT always
|
|
|
|
do $$
|
|
|
|
begin
|
|
|
|
raise notice 'foo';
|
|
|
|
raise exception 'bar';
|
|
|
|
end $$;
|