You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
postgres/src/bin/psql/t/010_tab_completion.pl

454 lines
13 KiB

# Copyright (c) 2021-2022, PostgreSQL Global Development Group
use strict;
use warnings;
use PostgreSQL::Test::Cluster;
use PostgreSQL::Test::Utils;
use Test::More;
use IPC::Run qw(pump finish timer);
use Data::Dumper;
# Do nothing unless Makefile has told us that the build is --with-readline.
if (!defined($ENV{with_readline}) || $ENV{with_readline} ne 'yes')
{
plan skip_all => 'readline is not supported by this build';
}
# Also, skip if user has set environment variable to command that.
# This is mainly intended to allow working around some of the more broken
# versions of libedit --- some users might find them acceptable even if
# they won't pass these tests.
if (defined($ENV{SKIP_READLINE_TESTS}))
{
plan skip_all => 'SKIP_READLINE_TESTS is set';
}
# If we don't have IO::Pty, forget it, because IPC::Run depends on that
# to support pty connections
eval { require IO::Pty; };
if ($@)
{
plan skip_all => 'IO::Pty is needed to run this test';
}
# start a new server
my $node = PostgreSQL::Test::Cluster->new('main');
$node->init;
$node->start;
# set up a few database objects
$node->safe_psql('postgres',
"CREATE TABLE tab1 (c1 int primary key, c2 text);\n"
. "CREATE TABLE mytab123 (f1 int, f2 text);\n"
. "CREATE TABLE mytab246 (f1 int, f2 text);\n"
psql: improve tab-complete's handling of variant SQL names. This patch improves tab completion's ability to deal with valid variant spellings of SQL identifiers. Notably: * Unquoted upper-case identifiers are now downcased as the backend would do, allowing them to be completed correctly. * Tab completion can now match identifiers that are quoted even though they don't need to be; for example "f<TAB> now completes to "foo" if that's the only available name. Previously, only names that require quotes would be offered. * Schema-qualified identifiers are now supported where SQL syntax allows it; many lesser-used completion rules neglected this. * Completion operations that refer back to some previously-typed name (for example, to complete names of columns belonging to a previously-mentioned table) now allow variant spellings of the previous name too. In addition, performance of tab completion queries has been improved for databases containing many objects, although you'd only be likely to notice with a heavily-loaded server. Authors of future tab-completion patches should note that this commit changes many details about how tab completion queries must be written: * Tab completion queries now deal in raw object names; do not use quote_ident(). * The name-matching restriction in a query must now be written as "outputcol LIKE '%s'", not "substring(outputcol,1,%d)='%s'". * The SchemaQuery mechanism has been extended so that it can handle queries that refer back to a previous name. Most completion queries that do that should be converted to SchemaQuery form. Only consider using a literal query if the previous name can never be schema-qualified. Don't use a literal query if the name-to-be-completed can validly be schema-qualified, either. * Use set_completion_reference() to specify which word is the previous name to consider, for either a SchemaQuery or a literal query. * If you want to offer some keywords in addition to a query result (for example, offer COLUMN in addition to column names after "ALTER TABLE t RENAME"), do not use the old hack of tacking the keywords on with UNION. Instead use the new QUERY_PLUS macros to write such keywords separately from the query proper. The "addon" macro arguments that used to be used for this purpose are gone. * If your query returns something that's not a SQL identifier (such as an attribute number or enum label), use the new QUERY_VERBATIM macros to prevent the result from incorrectly getting double-quoted. You may still need to use quote_literal in such a query, too. Tom Lane and Haiying Tang Discussion: https://postgr.es/m/a63cbd45e3884cf9b3961c2a6a95dcb7@G08CNEXMBPEKD05.g08.fujitsu.local
4 years ago
. "CREATE TABLE \"mixedName\" (f1 int, f2 text);\n"
. "CREATE TYPE enum1 AS ENUM ('foo', 'bar', 'baz', 'BLACK');\n"
. "CREATE PUBLICATION some_publication;\n");
# Developers would not appreciate this test adding a bunch of junk to
# their ~/.psql_history, so be sure to redirect history into a temp file.
# We might as well put it in the test log directory, so that buildfarm runs
# capture the result for possible debugging purposes.
my $historyfile = "${PostgreSQL::Test::Utils::log_path}/010_psql_history.txt";
$ENV{PSQL_HISTORY} = $historyfile;
# Another pitfall for developers is that they might have a ~/.inputrc
# file that changes readline's behavior enough to affect this test.
# So ignore any such file.
$ENV{INPUTRC} = '/dev/null';
# Unset $TERM so that readline/libedit won't use any terminal-dependent
# escape sequences; that leads to way too many cross-version variations
# in the output.
delete $ENV{TERM};
# Some versions of readline inspect LS_COLORS, so for luck unset that too.
delete $ENV{LS_COLORS};
Improve psql's tab completion for filenames. The Readline library contains a fair amount of knowledge about how to tab-complete filenames, but it turns out that that doesn't work too well unless we follow its expectation that we use its filename quoting hooks to quote and de-quote filenames. We were trying to do such quote handling within complete_from_files(), and that's still what we have to do if we're using libedit, which lacks those hooks. But for Readline, it works a lot better if we tell Readline that single-quote is a quoting character and then provide hooks that know the details of the quoting rules for SQL and psql meta-commands. Hence, resurrect the quoting hook functions that existed in the original version of tab-complete.c (and were disabled by commit f6689a328 because they "didn't work so well yet"), and whack on them until they do seem to work well. Notably, this fixes bug #16059 from Steven Winfield, who pointed out that the previous coding would strip quote marks from filenames in SQL COPY commands, even though they're syntactically necessary there. Now, we not only don't do that, but we'll add a quote mark when you tab-complete, even if you didn't type one. Getting this to work across a range of libedit versions (and, to a lesser extent, libreadline versions) was depressingly difficult. It will be interesting to see whether the new regression test cases pass everywhere in the buildfarm. Some future patch might try to handle quoted SQL identifiers with similar explicit quoting/dequoting logic, but that's for another day. Patch by me, reviewed by Peter Eisentraut. Discussion: https://postgr.es/m/16059-8836946734c02b84@postgresql.org
6 years ago
# In a VPATH build, we'll be started in the source directory, but we want
# to run in the build directory so that we can use relative paths to
# access the tab_comp_dir subdirectory; otherwise the output from filename
Improve psql's tab completion for filenames. The Readline library contains a fair amount of knowledge about how to tab-complete filenames, but it turns out that that doesn't work too well unless we follow its expectation that we use its filename quoting hooks to quote and de-quote filenames. We were trying to do such quote handling within complete_from_files(), and that's still what we have to do if we're using libedit, which lacks those hooks. But for Readline, it works a lot better if we tell Readline that single-quote is a quoting character and then provide hooks that know the details of the quoting rules for SQL and psql meta-commands. Hence, resurrect the quoting hook functions that existed in the original version of tab-complete.c (and were disabled by commit f6689a328 because they "didn't work so well yet"), and whack on them until they do seem to work well. Notably, this fixes bug #16059 from Steven Winfield, who pointed out that the previous coding would strip quote marks from filenames in SQL COPY commands, even though they're syntactically necessary there. Now, we not only don't do that, but we'll add a quote mark when you tab-complete, even if you didn't type one. Getting this to work across a range of libedit versions (and, to a lesser extent, libreadline versions) was depressingly difficult. It will be interesting to see whether the new regression test cases pass everywhere in the buildfarm. Some future patch might try to handle quoted SQL identifiers with similar explicit quoting/dequoting logic, but that's for another day. Patch by me, reviewed by Peter Eisentraut. Discussion: https://postgr.es/m/16059-8836946734c02b84@postgresql.org
6 years ago
# completion tests is too variable.
if ($ENV{TESTDATADIR})
Improve psql's tab completion for filenames. The Readline library contains a fair amount of knowledge about how to tab-complete filenames, but it turns out that that doesn't work too well unless we follow its expectation that we use its filename quoting hooks to quote and de-quote filenames. We were trying to do such quote handling within complete_from_files(), and that's still what we have to do if we're using libedit, which lacks those hooks. But for Readline, it works a lot better if we tell Readline that single-quote is a quoting character and then provide hooks that know the details of the quoting rules for SQL and psql meta-commands. Hence, resurrect the quoting hook functions that existed in the original version of tab-complete.c (and were disabled by commit f6689a328 because they "didn't work so well yet"), and whack on them until they do seem to work well. Notably, this fixes bug #16059 from Steven Winfield, who pointed out that the previous coding would strip quote marks from filenames in SQL COPY commands, even though they're syntactically necessary there. Now, we not only don't do that, but we'll add a quote mark when you tab-complete, even if you didn't type one. Getting this to work across a range of libedit versions (and, to a lesser extent, libreadline versions) was depressingly difficult. It will be interesting to see whether the new regression test cases pass everywhere in the buildfarm. Some future patch might try to handle quoted SQL identifiers with similar explicit quoting/dequoting logic, but that's for another day. Patch by me, reviewed by Peter Eisentraut. Discussion: https://postgr.es/m/16059-8836946734c02b84@postgresql.org
6 years ago
{
chdir $ENV{TESTDATADIR} or die "could not chdir to \"$ENV{TESTDATADIR}\": $!";
Improve psql's tab completion for filenames. The Readline library contains a fair amount of knowledge about how to tab-complete filenames, but it turns out that that doesn't work too well unless we follow its expectation that we use its filename quoting hooks to quote and de-quote filenames. We were trying to do such quote handling within complete_from_files(), and that's still what we have to do if we're using libedit, which lacks those hooks. But for Readline, it works a lot better if we tell Readline that single-quote is a quoting character and then provide hooks that know the details of the quoting rules for SQL and psql meta-commands. Hence, resurrect the quoting hook functions that existed in the original version of tab-complete.c (and were disabled by commit f6689a328 because they "didn't work so well yet"), and whack on them until they do seem to work well. Notably, this fixes bug #16059 from Steven Winfield, who pointed out that the previous coding would strip quote marks from filenames in SQL COPY commands, even though they're syntactically necessary there. Now, we not only don't do that, but we'll add a quote mark when you tab-complete, even if you didn't type one. Getting this to work across a range of libedit versions (and, to a lesser extent, libreadline versions) was depressingly difficult. It will be interesting to see whether the new regression test cases pass everywhere in the buildfarm. Some future patch might try to handle quoted SQL identifiers with similar explicit quoting/dequoting logic, but that's for another day. Patch by me, reviewed by Peter Eisentraut. Discussion: https://postgr.es/m/16059-8836946734c02b84@postgresql.org
6 years ago
}
# Create some junk files for filename completion testing.
mkdir "tab_comp_dir";
Improve psql's tab completion for filenames. The Readline library contains a fair amount of knowledge about how to tab-complete filenames, but it turns out that that doesn't work too well unless we follow its expectation that we use its filename quoting hooks to quote and de-quote filenames. We were trying to do such quote handling within complete_from_files(), and that's still what we have to do if we're using libedit, which lacks those hooks. But for Readline, it works a lot better if we tell Readline that single-quote is a quoting character and then provide hooks that know the details of the quoting rules for SQL and psql meta-commands. Hence, resurrect the quoting hook functions that existed in the original version of tab-complete.c (and were disabled by commit f6689a328 because they "didn't work so well yet"), and whack on them until they do seem to work well. Notably, this fixes bug #16059 from Steven Winfield, who pointed out that the previous coding would strip quote marks from filenames in SQL COPY commands, even though they're syntactically necessary there. Now, we not only don't do that, but we'll add a quote mark when you tab-complete, even if you didn't type one. Getting this to work across a range of libedit versions (and, to a lesser extent, libreadline versions) was depressingly difficult. It will be interesting to see whether the new regression test cases pass everywhere in the buildfarm. Some future patch might try to handle quoted SQL identifiers with similar explicit quoting/dequoting logic, but that's for another day. Patch by me, reviewed by Peter Eisentraut. Discussion: https://postgr.es/m/16059-8836946734c02b84@postgresql.org
6 years ago
my $FH;
open $FH, ">", "tab_comp_dir/somefile"
or die("could not create file \"tab_comp_dir/somefile\": $!");
Improve psql's tab completion for filenames. The Readline library contains a fair amount of knowledge about how to tab-complete filenames, but it turns out that that doesn't work too well unless we follow its expectation that we use its filename quoting hooks to quote and de-quote filenames. We were trying to do such quote handling within complete_from_files(), and that's still what we have to do if we're using libedit, which lacks those hooks. But for Readline, it works a lot better if we tell Readline that single-quote is a quoting character and then provide hooks that know the details of the quoting rules for SQL and psql meta-commands. Hence, resurrect the quoting hook functions that existed in the original version of tab-complete.c (and were disabled by commit f6689a328 because they "didn't work so well yet"), and whack on them until they do seem to work well. Notably, this fixes bug #16059 from Steven Winfield, who pointed out that the previous coding would strip quote marks from filenames in SQL COPY commands, even though they're syntactically necessary there. Now, we not only don't do that, but we'll add a quote mark when you tab-complete, even if you didn't type one. Getting this to work across a range of libedit versions (and, to a lesser extent, libreadline versions) was depressingly difficult. It will be interesting to see whether the new regression test cases pass everywhere in the buildfarm. Some future patch might try to handle quoted SQL identifiers with similar explicit quoting/dequoting logic, but that's for another day. Patch by me, reviewed by Peter Eisentraut. Discussion: https://postgr.es/m/16059-8836946734c02b84@postgresql.org
6 years ago
print $FH "some stuff\n";
close $FH;
open $FH, ">", "tab_comp_dir/afile123"
or die("could not create file \"tab_comp_dir/afile123\": $!");
Improve psql's tab completion for filenames. The Readline library contains a fair amount of knowledge about how to tab-complete filenames, but it turns out that that doesn't work too well unless we follow its expectation that we use its filename quoting hooks to quote and de-quote filenames. We were trying to do such quote handling within complete_from_files(), and that's still what we have to do if we're using libedit, which lacks those hooks. But for Readline, it works a lot better if we tell Readline that single-quote is a quoting character and then provide hooks that know the details of the quoting rules for SQL and psql meta-commands. Hence, resurrect the quoting hook functions that existed in the original version of tab-complete.c (and were disabled by commit f6689a328 because they "didn't work so well yet"), and whack on them until they do seem to work well. Notably, this fixes bug #16059 from Steven Winfield, who pointed out that the previous coding would strip quote marks from filenames in SQL COPY commands, even though they're syntactically necessary there. Now, we not only don't do that, but we'll add a quote mark when you tab-complete, even if you didn't type one. Getting this to work across a range of libedit versions (and, to a lesser extent, libreadline versions) was depressingly difficult. It will be interesting to see whether the new regression test cases pass everywhere in the buildfarm. Some future patch might try to handle quoted SQL identifiers with similar explicit quoting/dequoting logic, but that's for another day. Patch by me, reviewed by Peter Eisentraut. Discussion: https://postgr.es/m/16059-8836946734c02b84@postgresql.org
6 years ago
print $FH "more stuff\n";
close $FH;
open $FH, ">", "tab_comp_dir/afile456"
or die("could not create file \"tab_comp_dir/afile456\": $!");
Improve psql's tab completion for filenames. The Readline library contains a fair amount of knowledge about how to tab-complete filenames, but it turns out that that doesn't work too well unless we follow its expectation that we use its filename quoting hooks to quote and de-quote filenames. We were trying to do such quote handling within complete_from_files(), and that's still what we have to do if we're using libedit, which lacks those hooks. But for Readline, it works a lot better if we tell Readline that single-quote is a quoting character and then provide hooks that know the details of the quoting rules for SQL and psql meta-commands. Hence, resurrect the quoting hook functions that existed in the original version of tab-complete.c (and were disabled by commit f6689a328 because they "didn't work so well yet"), and whack on them until they do seem to work well. Notably, this fixes bug #16059 from Steven Winfield, who pointed out that the previous coding would strip quote marks from filenames in SQL COPY commands, even though they're syntactically necessary there. Now, we not only don't do that, but we'll add a quote mark when you tab-complete, even if you didn't type one. Getting this to work across a range of libedit versions (and, to a lesser extent, libreadline versions) was depressingly difficult. It will be interesting to see whether the new regression test cases pass everywhere in the buildfarm. Some future patch might try to handle quoted SQL identifiers with similar explicit quoting/dequoting logic, but that's for another day. Patch by me, reviewed by Peter Eisentraut. Discussion: https://postgr.es/m/16059-8836946734c02b84@postgresql.org
6 years ago
print $FH "other stuff\n";
close $FH;
# fire up an interactive psql session
my $in = '';
my $out = '';
my $timer = timer($PostgreSQL::Test::Utils::timeout_default);
my $h = $node->interactive_psql('postgres', \$in, \$out, $timer);
like($out, qr/psql/, "print startup banner");
# Simple test case: type something and see if psql responds as expected
sub check_completion
{
my ($send, $pattern, $annotation) = @_;
# report test failures from caller location
local $Test::Builder::Level = $Test::Builder::Level + 1;
# reset output collector
$out = "";
# restart per-command timer
$timer->start($PostgreSQL::Test::Utils::timeout_default);
# send the data to be sent
$in .= $send;
# wait ...
pump $h until ($out =~ $pattern || $timer->is_expired);
my $okay = ($out =~ $pattern && !$timer->is_expired);
ok($okay, $annotation);
# for debugging, log actual output if it didn't match
local $Data::Dumper::Terse = 1;
local $Data::Dumper::Useqq = 1;
diag 'Actual output was ' . Dumper($out) . "Did not match \"$pattern\"\n"
if !$okay;
return;
}
# Clear query buffer to start over
# (won't work if we are inside a string literal!)
sub clear_query
{
local $Test::Builder::Level = $Test::Builder::Level + 1;
check_completion("\\r\n", qr/Query buffer reset.*postgres=# /s,
"\\r works");
return;
}
Improve psql's tab completion for filenames. The Readline library contains a fair amount of knowledge about how to tab-complete filenames, but it turns out that that doesn't work too well unless we follow its expectation that we use its filename quoting hooks to quote and de-quote filenames. We were trying to do such quote handling within complete_from_files(), and that's still what we have to do if we're using libedit, which lacks those hooks. But for Readline, it works a lot better if we tell Readline that single-quote is a quoting character and then provide hooks that know the details of the quoting rules for SQL and psql meta-commands. Hence, resurrect the quoting hook functions that existed in the original version of tab-complete.c (and were disabled by commit f6689a328 because they "didn't work so well yet"), and whack on them until they do seem to work well. Notably, this fixes bug #16059 from Steven Winfield, who pointed out that the previous coding would strip quote marks from filenames in SQL COPY commands, even though they're syntactically necessary there. Now, we not only don't do that, but we'll add a quote mark when you tab-complete, even if you didn't type one. Getting this to work across a range of libedit versions (and, to a lesser extent, libreadline versions) was depressingly difficult. It will be interesting to see whether the new regression test cases pass everywhere in the buildfarm. Some future patch might try to handle quoted SQL identifiers with similar explicit quoting/dequoting logic, but that's for another day. Patch by me, reviewed by Peter Eisentraut. Discussion: https://postgr.es/m/16059-8836946734c02b84@postgresql.org
6 years ago
# Clear current line to start over
# (this will work in an incomplete string literal, but it's less desirable
# than clear_query because we lose evidence in the history file)
sub clear_line
{
local $Test::Builder::Level = $Test::Builder::Level + 1;
Improve psql's tab completion for filenames. The Readline library contains a fair amount of knowledge about how to tab-complete filenames, but it turns out that that doesn't work too well unless we follow its expectation that we use its filename quoting hooks to quote and de-quote filenames. We were trying to do such quote handling within complete_from_files(), and that's still what we have to do if we're using libedit, which lacks those hooks. But for Readline, it works a lot better if we tell Readline that single-quote is a quoting character and then provide hooks that know the details of the quoting rules for SQL and psql meta-commands. Hence, resurrect the quoting hook functions that existed in the original version of tab-complete.c (and were disabled by commit f6689a328 because they "didn't work so well yet"), and whack on them until they do seem to work well. Notably, this fixes bug #16059 from Steven Winfield, who pointed out that the previous coding would strip quote marks from filenames in SQL COPY commands, even though they're syntactically necessary there. Now, we not only don't do that, but we'll add a quote mark when you tab-complete, even if you didn't type one. Getting this to work across a range of libedit versions (and, to a lesser extent, libreadline versions) was depressingly difficult. It will be interesting to see whether the new regression test cases pass everywhere in the buildfarm. Some future patch might try to handle quoted SQL identifiers with similar explicit quoting/dequoting logic, but that's for another day. Patch by me, reviewed by Peter Eisentraut. Discussion: https://postgr.es/m/16059-8836946734c02b84@postgresql.org
6 years ago
check_completion("\025\n", qr/postgres=# /, "control-U works");
return;
}
# check basic command completion: SEL<tab> produces SELECT<space>
check_completion("SEL\t", qr/SELECT /, "complete SEL<tab> to SELECT");
clear_query();
# check case variation is honored
check_completion("sel\t", qr/select /, "complete sel<tab> to select");
# check basic table name completion
check_completion("* from t\t", qr/\* from tab1 /, "complete t<tab> to tab1");
clear_query();
# check table name completion with multiple alternatives
# note: readline might print a bell before the completion
check_completion(
"select * from my\t",
qr/select \* from my\a?tab/,
"complete my<tab> to mytab when there are multiple choices");
# some versions of readline/libedit require two tabs here, some only need one
check_completion(
"\t\t",
qr/mytab123 +mytab246/,
"offer multiple table choices");
check_completion("2\t", qr/246 /,
"finish completion of one of multiple table choices");
clear_query();
psql: improve tab-complete's handling of variant SQL names. This patch improves tab completion's ability to deal with valid variant spellings of SQL identifiers. Notably: * Unquoted upper-case identifiers are now downcased as the backend would do, allowing them to be completed correctly. * Tab completion can now match identifiers that are quoted even though they don't need to be; for example "f<TAB> now completes to "foo" if that's the only available name. Previously, only names that require quotes would be offered. * Schema-qualified identifiers are now supported where SQL syntax allows it; many lesser-used completion rules neglected this. * Completion operations that refer back to some previously-typed name (for example, to complete names of columns belonging to a previously-mentioned table) now allow variant spellings of the previous name too. In addition, performance of tab completion queries has been improved for databases containing many objects, although you'd only be likely to notice with a heavily-loaded server. Authors of future tab-completion patches should note that this commit changes many details about how tab completion queries must be written: * Tab completion queries now deal in raw object names; do not use quote_ident(). * The name-matching restriction in a query must now be written as "outputcol LIKE '%s'", not "substring(outputcol,1,%d)='%s'". * The SchemaQuery mechanism has been extended so that it can handle queries that refer back to a previous name. Most completion queries that do that should be converted to SchemaQuery form. Only consider using a literal query if the previous name can never be schema-qualified. Don't use a literal query if the name-to-be-completed can validly be schema-qualified, either. * Use set_completion_reference() to specify which word is the previous name to consider, for either a SchemaQuery or a literal query. * If you want to offer some keywords in addition to a query result (for example, offer COLUMN in addition to column names after "ALTER TABLE t RENAME"), do not use the old hack of tacking the keywords on with UNION. Instead use the new QUERY_PLUS macros to write such keywords separately from the query proper. The "addon" macro arguments that used to be used for this purpose are gone. * If your query returns something that's not a SQL identifier (such as an attribute number or enum label), use the new QUERY_VERBATIM macros to prevent the result from incorrectly getting double-quoted. You may still need to use quote_literal in such a query, too. Tom Lane and Haiying Tang Discussion: https://postgr.es/m/a63cbd45e3884cf9b3961c2a6a95dcb7@G08CNEXMBPEKD05.g08.fujitsu.local
4 years ago
# check handling of quoted names
check_completion(
"select * from \"my\t",
qr/select \* from "my\a?tab/,
"complete \"my<tab> to \"mytab when there are multiple choices");
check_completion(
"\t\t",
qr/"mytab123" +"mytab246"/,
"offer multiple quoted table choices");
# note: broken versions of libedit want to backslash the closing quote;
# not much we can do about that
check_completion("2\t", qr/246\\?" /,
psql: improve tab-complete's handling of variant SQL names. This patch improves tab completion's ability to deal with valid variant spellings of SQL identifiers. Notably: * Unquoted upper-case identifiers are now downcased as the backend would do, allowing them to be completed correctly. * Tab completion can now match identifiers that are quoted even though they don't need to be; for example "f<TAB> now completes to "foo" if that's the only available name. Previously, only names that require quotes would be offered. * Schema-qualified identifiers are now supported where SQL syntax allows it; many lesser-used completion rules neglected this. * Completion operations that refer back to some previously-typed name (for example, to complete names of columns belonging to a previously-mentioned table) now allow variant spellings of the previous name too. In addition, performance of tab completion queries has been improved for databases containing many objects, although you'd only be likely to notice with a heavily-loaded server. Authors of future tab-completion patches should note that this commit changes many details about how tab completion queries must be written: * Tab completion queries now deal in raw object names; do not use quote_ident(). * The name-matching restriction in a query must now be written as "outputcol LIKE '%s'", not "substring(outputcol,1,%d)='%s'". * The SchemaQuery mechanism has been extended so that it can handle queries that refer back to a previous name. Most completion queries that do that should be converted to SchemaQuery form. Only consider using a literal query if the previous name can never be schema-qualified. Don't use a literal query if the name-to-be-completed can validly be schema-qualified, either. * Use set_completion_reference() to specify which word is the previous name to consider, for either a SchemaQuery or a literal query. * If you want to offer some keywords in addition to a query result (for example, offer COLUMN in addition to column names after "ALTER TABLE t RENAME"), do not use the old hack of tacking the keywords on with UNION. Instead use the new QUERY_PLUS macros to write such keywords separately from the query proper. The "addon" macro arguments that used to be used for this purpose are gone. * If your query returns something that's not a SQL identifier (such as an attribute number or enum label), use the new QUERY_VERBATIM macros to prevent the result from incorrectly getting double-quoted. You may still need to use quote_literal in such a query, too. Tom Lane and Haiying Tang Discussion: https://postgr.es/m/a63cbd45e3884cf9b3961c2a6a95dcb7@G08CNEXMBPEKD05.g08.fujitsu.local
4 years ago
"finish completion of one of multiple quoted table choices");
# note: broken versions of libedit may leave us in a state where psql
# thinks there's an unclosed double quote, so that we have to use
# clear_line not clear_query here
clear_line();
psql: improve tab-complete's handling of variant SQL names. This patch improves tab completion's ability to deal with valid variant spellings of SQL identifiers. Notably: * Unquoted upper-case identifiers are now downcased as the backend would do, allowing them to be completed correctly. * Tab completion can now match identifiers that are quoted even though they don't need to be; for example "f<TAB> now completes to "foo" if that's the only available name. Previously, only names that require quotes would be offered. * Schema-qualified identifiers are now supported where SQL syntax allows it; many lesser-used completion rules neglected this. * Completion operations that refer back to some previously-typed name (for example, to complete names of columns belonging to a previously-mentioned table) now allow variant spellings of the previous name too. In addition, performance of tab completion queries has been improved for databases containing many objects, although you'd only be likely to notice with a heavily-loaded server. Authors of future tab-completion patches should note that this commit changes many details about how tab completion queries must be written: * Tab completion queries now deal in raw object names; do not use quote_ident(). * The name-matching restriction in a query must now be written as "outputcol LIKE '%s'", not "substring(outputcol,1,%d)='%s'". * The SchemaQuery mechanism has been extended so that it can handle queries that refer back to a previous name. Most completion queries that do that should be converted to SchemaQuery form. Only consider using a literal query if the previous name can never be schema-qualified. Don't use a literal query if the name-to-be-completed can validly be schema-qualified, either. * Use set_completion_reference() to specify which word is the previous name to consider, for either a SchemaQuery or a literal query. * If you want to offer some keywords in addition to a query result (for example, offer COLUMN in addition to column names after "ALTER TABLE t RENAME"), do not use the old hack of tacking the keywords on with UNION. Instead use the new QUERY_PLUS macros to write such keywords separately from the query proper. The "addon" macro arguments that used to be used for this purpose are gone. * If your query returns something that's not a SQL identifier (such as an attribute number or enum label), use the new QUERY_VERBATIM macros to prevent the result from incorrectly getting double-quoted. You may still need to use quote_literal in such a query, too. Tom Lane and Haiying Tang Discussion: https://postgr.es/m/a63cbd45e3884cf9b3961c2a6a95dcb7@G08CNEXMBPEKD05.g08.fujitsu.local
4 years ago
# check handling of mixed-case names
# note: broken versions of libedit want to backslash the closing quote;
# not much we can do about that
psql: improve tab-complete's handling of variant SQL names. This patch improves tab completion's ability to deal with valid variant spellings of SQL identifiers. Notably: * Unquoted upper-case identifiers are now downcased as the backend would do, allowing them to be completed correctly. * Tab completion can now match identifiers that are quoted even though they don't need to be; for example "f<TAB> now completes to "foo" if that's the only available name. Previously, only names that require quotes would be offered. * Schema-qualified identifiers are now supported where SQL syntax allows it; many lesser-used completion rules neglected this. * Completion operations that refer back to some previously-typed name (for example, to complete names of columns belonging to a previously-mentioned table) now allow variant spellings of the previous name too. In addition, performance of tab completion queries has been improved for databases containing many objects, although you'd only be likely to notice with a heavily-loaded server. Authors of future tab-completion patches should note that this commit changes many details about how tab completion queries must be written: * Tab completion queries now deal in raw object names; do not use quote_ident(). * The name-matching restriction in a query must now be written as "outputcol LIKE '%s'", not "substring(outputcol,1,%d)='%s'". * The SchemaQuery mechanism has been extended so that it can handle queries that refer back to a previous name. Most completion queries that do that should be converted to SchemaQuery form. Only consider using a literal query if the previous name can never be schema-qualified. Don't use a literal query if the name-to-be-completed can validly be schema-qualified, either. * Use set_completion_reference() to specify which word is the previous name to consider, for either a SchemaQuery or a literal query. * If you want to offer some keywords in addition to a query result (for example, offer COLUMN in addition to column names after "ALTER TABLE t RENAME"), do not use the old hack of tacking the keywords on with UNION. Instead use the new QUERY_PLUS macros to write such keywords separately from the query proper. The "addon" macro arguments that used to be used for this purpose are gone. * If your query returns something that's not a SQL identifier (such as an attribute number or enum label), use the new QUERY_VERBATIM macros to prevent the result from incorrectly getting double-quoted. You may still need to use quote_literal in such a query, too. Tom Lane and Haiying Tang Discussion: https://postgr.es/m/a63cbd45e3884cf9b3961c2a6a95dcb7@G08CNEXMBPEKD05.g08.fujitsu.local
4 years ago
check_completion(
"select * from \"mi\t",
qr/"mixedName\\?" /,
psql: improve tab-complete's handling of variant SQL names. This patch improves tab completion's ability to deal with valid variant spellings of SQL identifiers. Notably: * Unquoted upper-case identifiers are now downcased as the backend would do, allowing them to be completed correctly. * Tab completion can now match identifiers that are quoted even though they don't need to be; for example "f<TAB> now completes to "foo" if that's the only available name. Previously, only names that require quotes would be offered. * Schema-qualified identifiers are now supported where SQL syntax allows it; many lesser-used completion rules neglected this. * Completion operations that refer back to some previously-typed name (for example, to complete names of columns belonging to a previously-mentioned table) now allow variant spellings of the previous name too. In addition, performance of tab completion queries has been improved for databases containing many objects, although you'd only be likely to notice with a heavily-loaded server. Authors of future tab-completion patches should note that this commit changes many details about how tab completion queries must be written: * Tab completion queries now deal in raw object names; do not use quote_ident(). * The name-matching restriction in a query must now be written as "outputcol LIKE '%s'", not "substring(outputcol,1,%d)='%s'". * The SchemaQuery mechanism has been extended so that it can handle queries that refer back to a previous name. Most completion queries that do that should be converted to SchemaQuery form. Only consider using a literal query if the previous name can never be schema-qualified. Don't use a literal query if the name-to-be-completed can validly be schema-qualified, either. * Use set_completion_reference() to specify which word is the previous name to consider, for either a SchemaQuery or a literal query. * If you want to offer some keywords in addition to a query result (for example, offer COLUMN in addition to column names after "ALTER TABLE t RENAME"), do not use the old hack of tacking the keywords on with UNION. Instead use the new QUERY_PLUS macros to write such keywords separately from the query proper. The "addon" macro arguments that used to be used for this purpose are gone. * If your query returns something that's not a SQL identifier (such as an attribute number or enum label), use the new QUERY_VERBATIM macros to prevent the result from incorrectly getting double-quoted. You may still need to use quote_literal in such a query, too. Tom Lane and Haiying Tang Discussion: https://postgr.es/m/a63cbd45e3884cf9b3961c2a6a95dcb7@G08CNEXMBPEKD05.g08.fujitsu.local
4 years ago
"complete a mixed-case name");
# as above, must use clear_line not clear_query here
clear_line();
psql: improve tab-complete's handling of variant SQL names. This patch improves tab completion's ability to deal with valid variant spellings of SQL identifiers. Notably: * Unquoted upper-case identifiers are now downcased as the backend would do, allowing them to be completed correctly. * Tab completion can now match identifiers that are quoted even though they don't need to be; for example "f<TAB> now completes to "foo" if that's the only available name. Previously, only names that require quotes would be offered. * Schema-qualified identifiers are now supported where SQL syntax allows it; many lesser-used completion rules neglected this. * Completion operations that refer back to some previously-typed name (for example, to complete names of columns belonging to a previously-mentioned table) now allow variant spellings of the previous name too. In addition, performance of tab completion queries has been improved for databases containing many objects, although you'd only be likely to notice with a heavily-loaded server. Authors of future tab-completion patches should note that this commit changes many details about how tab completion queries must be written: * Tab completion queries now deal in raw object names; do not use quote_ident(). * The name-matching restriction in a query must now be written as "outputcol LIKE '%s'", not "substring(outputcol,1,%d)='%s'". * The SchemaQuery mechanism has been extended so that it can handle queries that refer back to a previous name. Most completion queries that do that should be converted to SchemaQuery form. Only consider using a literal query if the previous name can never be schema-qualified. Don't use a literal query if the name-to-be-completed can validly be schema-qualified, either. * Use set_completion_reference() to specify which word is the previous name to consider, for either a SchemaQuery or a literal query. * If you want to offer some keywords in addition to a query result (for example, offer COLUMN in addition to column names after "ALTER TABLE t RENAME"), do not use the old hack of tacking the keywords on with UNION. Instead use the new QUERY_PLUS macros to write such keywords separately from the query proper. The "addon" macro arguments that used to be used for this purpose are gone. * If your query returns something that's not a SQL identifier (such as an attribute number or enum label), use the new QUERY_VERBATIM macros to prevent the result from incorrectly getting double-quoted. You may still need to use quote_literal in such a query, too. Tom Lane and Haiying Tang Discussion: https://postgr.es/m/a63cbd45e3884cf9b3961c2a6a95dcb7@G08CNEXMBPEKD05.g08.fujitsu.local
4 years ago
# check case folding
check_completion("select * from TAB\t", qr/tab1 /, "automatically fold case");
psql: improve tab-complete's handling of variant SQL names. This patch improves tab completion's ability to deal with valid variant spellings of SQL identifiers. Notably: * Unquoted upper-case identifiers are now downcased as the backend would do, allowing them to be completed correctly. * Tab completion can now match identifiers that are quoted even though they don't need to be; for example "f<TAB> now completes to "foo" if that's the only available name. Previously, only names that require quotes would be offered. * Schema-qualified identifiers are now supported where SQL syntax allows it; many lesser-used completion rules neglected this. * Completion operations that refer back to some previously-typed name (for example, to complete names of columns belonging to a previously-mentioned table) now allow variant spellings of the previous name too. In addition, performance of tab completion queries has been improved for databases containing many objects, although you'd only be likely to notice with a heavily-loaded server. Authors of future tab-completion patches should note that this commit changes many details about how tab completion queries must be written: * Tab completion queries now deal in raw object names; do not use quote_ident(). * The name-matching restriction in a query must now be written as "outputcol LIKE '%s'", not "substring(outputcol,1,%d)='%s'". * The SchemaQuery mechanism has been extended so that it can handle queries that refer back to a previous name. Most completion queries that do that should be converted to SchemaQuery form. Only consider using a literal query if the previous name can never be schema-qualified. Don't use a literal query if the name-to-be-completed can validly be schema-qualified, either. * Use set_completion_reference() to specify which word is the previous name to consider, for either a SchemaQuery or a literal query. * If you want to offer some keywords in addition to a query result (for example, offer COLUMN in addition to column names after "ALTER TABLE t RENAME"), do not use the old hack of tacking the keywords on with UNION. Instead use the new QUERY_PLUS macros to write such keywords separately from the query proper. The "addon" macro arguments that used to be used for this purpose are gone. * If your query returns something that's not a SQL identifier (such as an attribute number or enum label), use the new QUERY_VERBATIM macros to prevent the result from incorrectly getting double-quoted. You may still need to use quote_literal in such a query, too. Tom Lane and Haiying Tang Discussion: https://postgr.es/m/a63cbd45e3884cf9b3961c2a6a95dcb7@G08CNEXMBPEKD05.g08.fujitsu.local
4 years ago
clear_query();
# check case-sensitive keyword replacement
# note: various versions of readline/libedit handle backspacing
# differently, so just check that the replacement comes out correctly
check_completion("\\DRD\t", qr/drds /, "complete \\DRD<tab> to \\drds");
# broken versions of libedit require clear_line not clear_query here
clear_line();
psql: improve tab-complete's handling of variant SQL names. This patch improves tab completion's ability to deal with valid variant spellings of SQL identifiers. Notably: * Unquoted upper-case identifiers are now downcased as the backend would do, allowing them to be completed correctly. * Tab completion can now match identifiers that are quoted even though they don't need to be; for example "f<TAB> now completes to "foo" if that's the only available name. Previously, only names that require quotes would be offered. * Schema-qualified identifiers are now supported where SQL syntax allows it; many lesser-used completion rules neglected this. * Completion operations that refer back to some previously-typed name (for example, to complete names of columns belonging to a previously-mentioned table) now allow variant spellings of the previous name too. In addition, performance of tab completion queries has been improved for databases containing many objects, although you'd only be likely to notice with a heavily-loaded server. Authors of future tab-completion patches should note that this commit changes many details about how tab completion queries must be written: * Tab completion queries now deal in raw object names; do not use quote_ident(). * The name-matching restriction in a query must now be written as "outputcol LIKE '%s'", not "substring(outputcol,1,%d)='%s'". * The SchemaQuery mechanism has been extended so that it can handle queries that refer back to a previous name. Most completion queries that do that should be converted to SchemaQuery form. Only consider using a literal query if the previous name can never be schema-qualified. Don't use a literal query if the name-to-be-completed can validly be schema-qualified, either. * Use set_completion_reference() to specify which word is the previous name to consider, for either a SchemaQuery or a literal query. * If you want to offer some keywords in addition to a query result (for example, offer COLUMN in addition to column names after "ALTER TABLE t RENAME"), do not use the old hack of tacking the keywords on with UNION. Instead use the new QUERY_PLUS macros to write such keywords separately from the query proper. The "addon" macro arguments that used to be used for this purpose are gone. * If your query returns something that's not a SQL identifier (such as an attribute number or enum label), use the new QUERY_VERBATIM macros to prevent the result from incorrectly getting double-quoted. You may still need to use quote_literal in such a query, too. Tom Lane and Haiying Tang Discussion: https://postgr.es/m/a63cbd45e3884cf9b3961c2a6a95dcb7@G08CNEXMBPEKD05.g08.fujitsu.local
4 years ago
# check completion of a schema-qualified name
check_completion("select * from pub\t",
qr/public\./, "complete schema when relevant");
psql: improve tab-complete's handling of variant SQL names. This patch improves tab completion's ability to deal with valid variant spellings of SQL identifiers. Notably: * Unquoted upper-case identifiers are now downcased as the backend would do, allowing them to be completed correctly. * Tab completion can now match identifiers that are quoted even though they don't need to be; for example "f<TAB> now completes to "foo" if that's the only available name. Previously, only names that require quotes would be offered. * Schema-qualified identifiers are now supported where SQL syntax allows it; many lesser-used completion rules neglected this. * Completion operations that refer back to some previously-typed name (for example, to complete names of columns belonging to a previously-mentioned table) now allow variant spellings of the previous name too. In addition, performance of tab completion queries has been improved for databases containing many objects, although you'd only be likely to notice with a heavily-loaded server. Authors of future tab-completion patches should note that this commit changes many details about how tab completion queries must be written: * Tab completion queries now deal in raw object names; do not use quote_ident(). * The name-matching restriction in a query must now be written as "outputcol LIKE '%s'", not "substring(outputcol,1,%d)='%s'". * The SchemaQuery mechanism has been extended so that it can handle queries that refer back to a previous name. Most completion queries that do that should be converted to SchemaQuery form. Only consider using a literal query if the previous name can never be schema-qualified. Don't use a literal query if the name-to-be-completed can validly be schema-qualified, either. * Use set_completion_reference() to specify which word is the previous name to consider, for either a SchemaQuery or a literal query. * If you want to offer some keywords in addition to a query result (for example, offer COLUMN in addition to column names after "ALTER TABLE t RENAME"), do not use the old hack of tacking the keywords on with UNION. Instead use the new QUERY_PLUS macros to write such keywords separately from the query proper. The "addon" macro arguments that used to be used for this purpose are gone. * If your query returns something that's not a SQL identifier (such as an attribute number or enum label), use the new QUERY_VERBATIM macros to prevent the result from incorrectly getting double-quoted. You may still need to use quote_literal in such a query, too. Tom Lane and Haiying Tang Discussion: https://postgr.es/m/a63cbd45e3884cf9b3961c2a6a95dcb7@G08CNEXMBPEKD05.g08.fujitsu.local
4 years ago
check_completion("tab\t", qr/tab1 /, "complete schema-qualified name");
psql: improve tab-complete's handling of variant SQL names. This patch improves tab completion's ability to deal with valid variant spellings of SQL identifiers. Notably: * Unquoted upper-case identifiers are now downcased as the backend would do, allowing them to be completed correctly. * Tab completion can now match identifiers that are quoted even though they don't need to be; for example "f<TAB> now completes to "foo" if that's the only available name. Previously, only names that require quotes would be offered. * Schema-qualified identifiers are now supported where SQL syntax allows it; many lesser-used completion rules neglected this. * Completion operations that refer back to some previously-typed name (for example, to complete names of columns belonging to a previously-mentioned table) now allow variant spellings of the previous name too. In addition, performance of tab completion queries has been improved for databases containing many objects, although you'd only be likely to notice with a heavily-loaded server. Authors of future tab-completion patches should note that this commit changes many details about how tab completion queries must be written: * Tab completion queries now deal in raw object names; do not use quote_ident(). * The name-matching restriction in a query must now be written as "outputcol LIKE '%s'", not "substring(outputcol,1,%d)='%s'". * The SchemaQuery mechanism has been extended so that it can handle queries that refer back to a previous name. Most completion queries that do that should be converted to SchemaQuery form. Only consider using a literal query if the previous name can never be schema-qualified. Don't use a literal query if the name-to-be-completed can validly be schema-qualified, either. * Use set_completion_reference() to specify which word is the previous name to consider, for either a SchemaQuery or a literal query. * If you want to offer some keywords in addition to a query result (for example, offer COLUMN in addition to column names after "ALTER TABLE t RENAME"), do not use the old hack of tacking the keywords on with UNION. Instead use the new QUERY_PLUS macros to write such keywords separately from the query proper. The "addon" macro arguments that used to be used for this purpose are gone. * If your query returns something that's not a SQL identifier (such as an attribute number or enum label), use the new QUERY_VERBATIM macros to prevent the result from incorrectly getting double-quoted. You may still need to use quote_literal in such a query, too. Tom Lane and Haiying Tang Discussion: https://postgr.es/m/a63cbd45e3884cf9b3961c2a6a95dcb7@G08CNEXMBPEKD05.g08.fujitsu.local
4 years ago
clear_query();
check_completion(
"select * from PUBLIC.t\t",
qr/public\.tab1 /,
"automatically fold case in schema-qualified name");
clear_query();
# check interpretation of referenced names
check_completion(
"alter table tab1 drop constraint \t",
qr/tab1_pkey /,
"complete index name for referenced table");
clear_query();
check_completion(
"alter table TAB1 drop constraint \t",
qr/tab1_pkey /,
"complete index name for referenced table, with downcasing");
clear_query();
check_completion(
"alter table public.\"tab1\" drop constraint \t",
qr/tab1_pkey /,
"complete index name for referenced table, with schema and quoting");
clear_query();
# check variant where we're completing a qualified name from a refname
# (this one also checks successful completion in a multiline command)
check_completion(
"comment on constraint tab1_pkey \n on public.\t",
qr/public\.tab1/,
"complete qualified name from object reference");
clear_query();
Improve psql's tab completion for filenames. The Readline library contains a fair amount of knowledge about how to tab-complete filenames, but it turns out that that doesn't work too well unless we follow its expectation that we use its filename quoting hooks to quote and de-quote filenames. We were trying to do such quote handling within complete_from_files(), and that's still what we have to do if we're using libedit, which lacks those hooks. But for Readline, it works a lot better if we tell Readline that single-quote is a quoting character and then provide hooks that know the details of the quoting rules for SQL and psql meta-commands. Hence, resurrect the quoting hook functions that existed in the original version of tab-complete.c (and were disabled by commit f6689a328 because they "didn't work so well yet"), and whack on them until they do seem to work well. Notably, this fixes bug #16059 from Steven Winfield, who pointed out that the previous coding would strip quote marks from filenames in SQL COPY commands, even though they're syntactically necessary there. Now, we not only don't do that, but we'll add a quote mark when you tab-complete, even if you didn't type one. Getting this to work across a range of libedit versions (and, to a lesser extent, libreadline versions) was depressingly difficult. It will be interesting to see whether the new regression test cases pass everywhere in the buildfarm. Some future patch might try to handle quoted SQL identifiers with similar explicit quoting/dequoting logic, but that's for another day. Patch by me, reviewed by Peter Eisentraut. Discussion: https://postgr.es/m/16059-8836946734c02b84@postgresql.org
6 years ago
# check filename completion
check_completion(
"\\lo_import tab_comp_dir/some\t",
qr|tab_comp_dir/somefile |,
Improve psql's tab completion for filenames. The Readline library contains a fair amount of knowledge about how to tab-complete filenames, but it turns out that that doesn't work too well unless we follow its expectation that we use its filename quoting hooks to quote and de-quote filenames. We were trying to do such quote handling within complete_from_files(), and that's still what we have to do if we're using libedit, which lacks those hooks. But for Readline, it works a lot better if we tell Readline that single-quote is a quoting character and then provide hooks that know the details of the quoting rules for SQL and psql meta-commands. Hence, resurrect the quoting hook functions that existed in the original version of tab-complete.c (and were disabled by commit f6689a328 because they "didn't work so well yet"), and whack on them until they do seem to work well. Notably, this fixes bug #16059 from Steven Winfield, who pointed out that the previous coding would strip quote marks from filenames in SQL COPY commands, even though they're syntactically necessary there. Now, we not only don't do that, but we'll add a quote mark when you tab-complete, even if you didn't type one. Getting this to work across a range of libedit versions (and, to a lesser extent, libreadline versions) was depressingly difficult. It will be interesting to see whether the new regression test cases pass everywhere in the buildfarm. Some future patch might try to handle quoted SQL identifiers with similar explicit quoting/dequoting logic, but that's for another day. Patch by me, reviewed by Peter Eisentraut. Discussion: https://postgr.es/m/16059-8836946734c02b84@postgresql.org
6 years ago
"filename completion with one possibility");
clear_query();
# note: readline might print a bell before the completion
check_completion(
"\\lo_import tab_comp_dir/af\t",
qr|tab_comp_dir/af\a?ile|,
Improve psql's tab completion for filenames. The Readline library contains a fair amount of knowledge about how to tab-complete filenames, but it turns out that that doesn't work too well unless we follow its expectation that we use its filename quoting hooks to quote and de-quote filenames. We were trying to do such quote handling within complete_from_files(), and that's still what we have to do if we're using libedit, which lacks those hooks. But for Readline, it works a lot better if we tell Readline that single-quote is a quoting character and then provide hooks that know the details of the quoting rules for SQL and psql meta-commands. Hence, resurrect the quoting hook functions that existed in the original version of tab-complete.c (and were disabled by commit f6689a328 because they "didn't work so well yet"), and whack on them until they do seem to work well. Notably, this fixes bug #16059 from Steven Winfield, who pointed out that the previous coding would strip quote marks from filenames in SQL COPY commands, even though they're syntactically necessary there. Now, we not only don't do that, but we'll add a quote mark when you tab-complete, even if you didn't type one. Getting this to work across a range of libedit versions (and, to a lesser extent, libreadline versions) was depressingly difficult. It will be interesting to see whether the new regression test cases pass everywhere in the buildfarm. Some future patch might try to handle quoted SQL identifiers with similar explicit quoting/dequoting logic, but that's for another day. Patch by me, reviewed by Peter Eisentraut. Discussion: https://postgr.es/m/16059-8836946734c02b84@postgresql.org
6 years ago
"filename completion with multiple possibilities");
# broken versions of libedit require clear_line not clear_query here
clear_line();
Improve psql's tab completion for filenames. The Readline library contains a fair amount of knowledge about how to tab-complete filenames, but it turns out that that doesn't work too well unless we follow its expectation that we use its filename quoting hooks to quote and de-quote filenames. We were trying to do such quote handling within complete_from_files(), and that's still what we have to do if we're using libedit, which lacks those hooks. But for Readline, it works a lot better if we tell Readline that single-quote is a quoting character and then provide hooks that know the details of the quoting rules for SQL and psql meta-commands. Hence, resurrect the quoting hook functions that existed in the original version of tab-complete.c (and were disabled by commit f6689a328 because they "didn't work so well yet"), and whack on them until they do seem to work well. Notably, this fixes bug #16059 from Steven Winfield, who pointed out that the previous coding would strip quote marks from filenames in SQL COPY commands, even though they're syntactically necessary there. Now, we not only don't do that, but we'll add a quote mark when you tab-complete, even if you didn't type one. Getting this to work across a range of libedit versions (and, to a lesser extent, libreadline versions) was depressingly difficult. It will be interesting to see whether the new regression test cases pass everywhere in the buildfarm. Some future patch might try to handle quoted SQL identifiers with similar explicit quoting/dequoting logic, but that's for another day. Patch by me, reviewed by Peter Eisentraut. Discussion: https://postgr.es/m/16059-8836946734c02b84@postgresql.org
6 years ago
# COPY requires quoting
# note: broken versions of libedit want to backslash the closing quote;
# not much we can do about that
check_completion(
"COPY foo FROM tab_comp_dir/some\t",
qr|'tab_comp_dir/somefile\\?' |,
Improve psql's tab completion for filenames. The Readline library contains a fair amount of knowledge about how to tab-complete filenames, but it turns out that that doesn't work too well unless we follow its expectation that we use its filename quoting hooks to quote and de-quote filenames. We were trying to do such quote handling within complete_from_files(), and that's still what we have to do if we're using libedit, which lacks those hooks. But for Readline, it works a lot better if we tell Readline that single-quote is a quoting character and then provide hooks that know the details of the quoting rules for SQL and psql meta-commands. Hence, resurrect the quoting hook functions that existed in the original version of tab-complete.c (and were disabled by commit f6689a328 because they "didn't work so well yet"), and whack on them until they do seem to work well. Notably, this fixes bug #16059 from Steven Winfield, who pointed out that the previous coding would strip quote marks from filenames in SQL COPY commands, even though they're syntactically necessary there. Now, we not only don't do that, but we'll add a quote mark when you tab-complete, even if you didn't type one. Getting this to work across a range of libedit versions (and, to a lesser extent, libreadline versions) was depressingly difficult. It will be interesting to see whether the new regression test cases pass everywhere in the buildfarm. Some future patch might try to handle quoted SQL identifiers with similar explicit quoting/dequoting logic, but that's for another day. Patch by me, reviewed by Peter Eisentraut. Discussion: https://postgr.es/m/16059-8836946734c02b84@postgresql.org
6 years ago
"quoted filename completion with one possibility");
clear_line();
check_completion(
"COPY foo FROM tab_comp_dir/af\t",
qr|'tab_comp_dir/afile|,
Improve psql's tab completion for filenames. The Readline library contains a fair amount of knowledge about how to tab-complete filenames, but it turns out that that doesn't work too well unless we follow its expectation that we use its filename quoting hooks to quote and de-quote filenames. We were trying to do such quote handling within complete_from_files(), and that's still what we have to do if we're using libedit, which lacks those hooks. But for Readline, it works a lot better if we tell Readline that single-quote is a quoting character and then provide hooks that know the details of the quoting rules for SQL and psql meta-commands. Hence, resurrect the quoting hook functions that existed in the original version of tab-complete.c (and were disabled by commit f6689a328 because they "didn't work so well yet"), and whack on them until they do seem to work well. Notably, this fixes bug #16059 from Steven Winfield, who pointed out that the previous coding would strip quote marks from filenames in SQL COPY commands, even though they're syntactically necessary there. Now, we not only don't do that, but we'll add a quote mark when you tab-complete, even if you didn't type one. Getting this to work across a range of libedit versions (and, to a lesser extent, libreadline versions) was depressingly difficult. It will be interesting to see whether the new regression test cases pass everywhere in the buildfarm. Some future patch might try to handle quoted SQL identifiers with similar explicit quoting/dequoting logic, but that's for another day. Patch by me, reviewed by Peter Eisentraut. Discussion: https://postgr.es/m/16059-8836946734c02b84@postgresql.org
6 years ago
"quoted filename completion with multiple possibilities");
# some versions of readline/libedit require two tabs here, some only need one
# also, some will offer the whole path name and some just the file name
# the quotes might appear, too
check_completion(
"\t\t",
qr|afile123'? +'?(tab_comp_dir/)?afile456|,
Improve psql's tab completion for filenames. The Readline library contains a fair amount of knowledge about how to tab-complete filenames, but it turns out that that doesn't work too well unless we follow its expectation that we use its filename quoting hooks to quote and de-quote filenames. We were trying to do such quote handling within complete_from_files(), and that's still what we have to do if we're using libedit, which lacks those hooks. But for Readline, it works a lot better if we tell Readline that single-quote is a quoting character and then provide hooks that know the details of the quoting rules for SQL and psql meta-commands. Hence, resurrect the quoting hook functions that existed in the original version of tab-complete.c (and were disabled by commit f6689a328 because they "didn't work so well yet"), and whack on them until they do seem to work well. Notably, this fixes bug #16059 from Steven Winfield, who pointed out that the previous coding would strip quote marks from filenames in SQL COPY commands, even though they're syntactically necessary there. Now, we not only don't do that, but we'll add a quote mark when you tab-complete, even if you didn't type one. Getting this to work across a range of libedit versions (and, to a lesser extent, libreadline versions) was depressingly difficult. It will be interesting to see whether the new regression test cases pass everywhere in the buildfarm. Some future patch might try to handle quoted SQL identifiers with similar explicit quoting/dequoting logic, but that's for another day. Patch by me, reviewed by Peter Eisentraut. Discussion: https://postgr.es/m/16059-8836946734c02b84@postgresql.org
6 years ago
"offer multiple file choices");
clear_line();
# check enum label completion
# some versions of readline/libedit require two tabs here, some only need one
# also, some versions will offer quotes, some will not
check_completion(
"ALTER TYPE enum1 RENAME VALUE 'ba\t\t",
qr|'?bar'? +'?baz'?|,
"offer multiple enum choices");
clear_line();
psql: improve tab-complete's handling of variant SQL names. This patch improves tab completion's ability to deal with valid variant spellings of SQL identifiers. Notably: * Unquoted upper-case identifiers are now downcased as the backend would do, allowing them to be completed correctly. * Tab completion can now match identifiers that are quoted even though they don't need to be; for example "f<TAB> now completes to "foo" if that's the only available name. Previously, only names that require quotes would be offered. * Schema-qualified identifiers are now supported where SQL syntax allows it; many lesser-used completion rules neglected this. * Completion operations that refer back to some previously-typed name (for example, to complete names of columns belonging to a previously-mentioned table) now allow variant spellings of the previous name too. In addition, performance of tab completion queries has been improved for databases containing many objects, although you'd only be likely to notice with a heavily-loaded server. Authors of future tab-completion patches should note that this commit changes many details about how tab completion queries must be written: * Tab completion queries now deal in raw object names; do not use quote_ident(). * The name-matching restriction in a query must now be written as "outputcol LIKE '%s'", not "substring(outputcol,1,%d)='%s'". * The SchemaQuery mechanism has been extended so that it can handle queries that refer back to a previous name. Most completion queries that do that should be converted to SchemaQuery form. Only consider using a literal query if the previous name can never be schema-qualified. Don't use a literal query if the name-to-be-completed can validly be schema-qualified, either. * Use set_completion_reference() to specify which word is the previous name to consider, for either a SchemaQuery or a literal query. * If you want to offer some keywords in addition to a query result (for example, offer COLUMN in addition to column names after "ALTER TABLE t RENAME"), do not use the old hack of tacking the keywords on with UNION. Instead use the new QUERY_PLUS macros to write such keywords separately from the query proper. The "addon" macro arguments that used to be used for this purpose are gone. * If your query returns something that's not a SQL identifier (such as an attribute number or enum label), use the new QUERY_VERBATIM macros to prevent the result from incorrectly getting double-quoted. You may still need to use quote_literal in such a query, too. Tom Lane and Haiying Tang Discussion: https://postgr.es/m/a63cbd45e3884cf9b3961c2a6a95dcb7@G08CNEXMBPEKD05.g08.fujitsu.local
4 years ago
# enum labels are case sensitive, so this should complete BLACK immediately
check_completion(
"ALTER TYPE enum1 RENAME VALUE 'B\t",
qr|BLACK|,
"enum labels are case sensitive");
clear_line();
# check timezone name completion
check_completion("SET timezone TO am\t",
qr|'America/|, "offer partial timezone name");
check_completion("new_\t", qr|New_York|, "complete partial timezone name");
clear_line();
# check completion of a keyword offered in addition to object names;
# such a keyword should obey COMP_KEYWORD_CASE
foreach (
[ 'lower', 'CO', 'column' ],
[ 'upper', 'co', 'COLUMN' ],
[ 'preserve-lower', 'co', 'column' ],
[ 'preserve-upper', 'CO', 'COLUMN' ],)
{
my ($case, $in, $out) = @$_;
check_completion(
"\\set COMP_KEYWORD_CASE $case\n",
qr/postgres=#/,
"set completion case to '$case'");
check_completion("alter table tab1 rename $in\t\t\t",
qr|$out|,
"offer keyword $out for input $in<TAB>, COMP_KEYWORD_CASE = $case");
clear_query();
}
psql: improve tab-complete's handling of variant SQL names. This patch improves tab completion's ability to deal with valid variant spellings of SQL identifiers. Notably: * Unquoted upper-case identifiers are now downcased as the backend would do, allowing them to be completed correctly. * Tab completion can now match identifiers that are quoted even though they don't need to be; for example "f<TAB> now completes to "foo" if that's the only available name. Previously, only names that require quotes would be offered. * Schema-qualified identifiers are now supported where SQL syntax allows it; many lesser-used completion rules neglected this. * Completion operations that refer back to some previously-typed name (for example, to complete names of columns belonging to a previously-mentioned table) now allow variant spellings of the previous name too. In addition, performance of tab completion queries has been improved for databases containing many objects, although you'd only be likely to notice with a heavily-loaded server. Authors of future tab-completion patches should note that this commit changes many details about how tab completion queries must be written: * Tab completion queries now deal in raw object names; do not use quote_ident(). * The name-matching restriction in a query must now be written as "outputcol LIKE '%s'", not "substring(outputcol,1,%d)='%s'". * The SchemaQuery mechanism has been extended so that it can handle queries that refer back to a previous name. Most completion queries that do that should be converted to SchemaQuery form. Only consider using a literal query if the previous name can never be schema-qualified. Don't use a literal query if the name-to-be-completed can validly be schema-qualified, either. * Use set_completion_reference() to specify which word is the previous name to consider, for either a SchemaQuery or a literal query. * If you want to offer some keywords in addition to a query result (for example, offer COLUMN in addition to column names after "ALTER TABLE t RENAME"), do not use the old hack of tacking the keywords on with UNION. Instead use the new QUERY_PLUS macros to write such keywords separately from the query proper. The "addon" macro arguments that used to be used for this purpose are gone. * If your query returns something that's not a SQL identifier (such as an attribute number or enum label), use the new QUERY_VERBATIM macros to prevent the result from incorrectly getting double-quoted. You may still need to use quote_literal in such a query, too. Tom Lane and Haiying Tang Discussion: https://postgr.es/m/a63cbd45e3884cf9b3961c2a6a95dcb7@G08CNEXMBPEKD05.g08.fujitsu.local
4 years ago
# alternate path where keyword comes from SchemaQuery
check_completion(
"DROP TYPE big\t",
qr/DROP TYPE bigint /,
"offer keyword from SchemaQuery");
clear_query();
# check create_command_generator
check_completion(
"CREATE TY\t",
qr/CREATE TYPE /,
"check create_command_generator");
clear_query();
# check words_after_create infrastructure
check_completion(
"CREATE TABLE mytab\t\t",
qr/mytab123 +mytab246/,
"check words_after_create");
clear_query();
# check VersionedQuery infrastructure
check_completion(
"DROP PUBLIC\t \t\t",
qr/DROP PUBLICATION\s+some_publication /,
"check VersionedQuery");
clear_query();
# hits ends_with() and logic for completing in multi-line queries
check_completion("analyze (\n\t\t", qr/VERBOSE/,
"check ANALYZE (VERBOSE ...");
clear_query();
# check completions for GUCs
check_completion(
"set interval\t\t",
qr/intervalstyle TO/,
"complete a GUC name");
check_completion(" iso\t", qr/iso_8601 /, "complete a GUC enum value");
clear_query();
# same, for qualified GUC names
check_completion(
"DO \$\$begin end\$\$ LANGUAGE plpgsql;\n",
qr/postgres=# /,
"load plpgsql extension");
check_completion("set plpg\t", qr/plpg\a?sql\./,
"complete prefix of a GUC name");
check_completion(
"var\t\t",
qr/variable_conflict TO/,
"complete a qualified GUC name");
check_completion(" USE_C\t",
qr/use_column/, "complete a qualified GUC enum value");
clear_query();
# check completions for psql variables
check_completion("\\set VERB\t", qr/VERBOSITY /,
"complete a psql variable name");
check_completion("def\t", qr/default /, "complete a psql variable value");
clear_query();
check_completion(
"\\echo :VERB\t",
qr/:VERBOSITY /,
"complete an interpolated psql variable name");
clear_query();
# check no-completions code path
check_completion("blarg \t\t", qr//, "check completion failure path");
clear_query();
# send psql an explicit \q to shut it down, else pty won't close properly
$timer->start($PostgreSQL::Test::Utils::timeout_default);
$in .= "\\q\n";
finish $h or die "psql returned $?";
$timer->reset;
# done
$node->stop;
done_testing();