Обсуждение: proposal: psql autocomplete for casting

Поиск
Список
Период
Сортировка

proposal: psql autocomplete for casting

От
Pavel Stehule
Дата:
Hi

We have  not autocomplete for casting introduced by symbol "::". A implementation should not be hard.

Regards

Pavel

Re: proposal: psql autocomplete for casting

От
Kyotaro HORIGUCHI
Дата:
Hello, I considered on this,

At Thu, 3 Mar 2016 10:05:06 +0100, Pavel Stehule <pavel.stehule@gmail.com> wrote in
<CAFj8pRDZ456OKbpV9jDJ_VCgTWprqxYu1kQp6z_Eu_WgNvs57Q@mail.gmail.com>
> We have  not autocomplete for casting introduced by symbol "::". A
> implementation should not be hard.

Completion needs a sequence of break characters between two
succeeding words and the break characters cannot be a part of a
word. If cast operators are allowed to be preceded by white
space, the following diff gives maybe-desired behavior.

===
--- a/src/bin/psql/tab-complete.c
+++ b/src/bin/psql/tab-complete.c
@@ -1322,6 +1322,8 @@ psql_completion(const char *text, int start, int end)               else
matches= complete_from_variables(text, ":", "", true);       }
 
+       else if (text[0] == ':' && text[1] == ':')
+        COMPLETE_WITH_LIST3("::integer", "::text", "::date");       /* If no previous word, suggest one of the basic
sqlcommands */       else if (previous_words_count == 0)
 
===

> =# select 123 ::<tab>
> ::DATE     ::INTEGER  ::TEXT    
> =# select 123 ::T<tab>
> =# select 123 ::TEXT 

It might not be instinctive but would be doable by making such a
candidate list.

====
diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c
index 5f27120..179c9f0 100644
--- a/src/bin/psql/tab-complete.c
+++ b/src/bin/psql/tab-complete.c
@@ -1322,6 +1322,8 @@ psql_completion(const char *text, int start, int end)               else
matches= complete_from_variables(text, ":", "", true);       }
 
+       else if (text[0] == ':' && text[1] == ':')
+               COMPLETE_WITH_QUERY("SELECT distinct('::' || typname) FROM pg_type where typname !~'^(pg)?_.*'");
/*If no previous word, suggest one of the basic sql commands */       else if (previous_words_count == 0)
 
====

> =# select 2314 ::t<tab>
> ::t                         ::tinterval
> ::table_constraints         ::transforms
> ::table_privileges          ::trigger
> ::tables                    ::triggered_update_columns
> ::text                      ::triggers
> ::tid                       ::tsm_handler
> ::time                      ::tsquery
> ::timestamp                 ::tsrange
> ::time_stamp                ::tstzrange
> ::timestamptz               ::tsvector
> ::timetz                    ::txid_snapshot

Does this make sense?

regards,

-- 
Kyotaro Horiguchi
NTT Open Source Software Center





Re: proposal: psql autocomplete for casting

От
Pavel Stehule
Дата:


2016-03-03 12:06 GMT+01:00 Kyotaro HORIGUCHI <horiguchi.kyotaro@lab.ntt.co.jp>:
Hello, I considered on this,

At Thu, 3 Mar 2016 10:05:06 +0100, Pavel Stehule <pavel.stehule@gmail.com> wrote in <CAFj8pRDZ456OKbpV9jDJ_VCgTWprqxYu1kQp6z_Eu_WgNvs57Q@mail.gmail.com>
> We have  not autocomplete for casting introduced by symbol "::". A
> implementation should not be hard.

Completion needs a sequence of break characters between two
succeeding words and the break characters cannot be a part of a
word. If cast operators are allowed to be preceded by white
space, the following diff gives maybe-desired behavior.

===
--- a/src/bin/psql/tab-complete.c
+++ b/src/bin/psql/tab-complete.c
@@ -1322,6 +1322,8 @@ psql_completion(const char *text, int start, int end)
                else
                        matches = complete_from_variables(text, ":", "", true);
        }
+       else if (text[0] == ':' && text[1] == ':')
+               COMPLETE_WITH_LIST3("::integer", "::text", "::date");

        /* If no previous word, suggest one of the basic sql commands */
        else if (previous_words_count == 0)
===

> =# select 123 ::<tab>
> ::DATE     ::INTEGER  ::TEXT
> =# select 123 ::T<tab>
> =# select 123 ::TEXT

It might not be instinctive but would be doable by making such a
candidate list.

====
diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c
index 5f27120..179c9f0 100644
--- a/src/bin/psql/tab-complete.c
+++ b/src/bin/psql/tab-complete.c
@@ -1322,6 +1322,8 @@ psql_completion(const char *text, int start, int end)
                else
                        matches = complete_from_variables(text, ":", "", true);
        }
+       else if (text[0] == ':' && text[1] == ':')
+               COMPLETE_WITH_QUERY("SELECT distinct('::' || typname) FROM pg_type where typname !~'^(pg)?_.*'");

        /* If no previous word, suggest one of the basic sql commands */
        else if (previous_words_count == 0)
====

> =# select 2314 ::t<tab>
> ::t                         ::tinterval
> ::table_constraints         ::transforms
> ::table_privileges          ::trigger
> ::tables                    ::triggered_update_columns
> ::text                      ::triggers
> ::tid                       ::tsm_handler
> ::time                      ::tsquery
> ::timestamp                 ::tsrange
> ::time_stamp                ::tstzrange
> ::timestamptz               ::tsvector
> ::timetz                    ::txid_snapshot

Does this make sense?

the requirement of space before is not good :( - It should be any different than operator chars. Not only space.

all other is perfect :)

Regards

Pavel
 

regards,

--
Kyotaro Horiguchi
NTT Open Source Software Center



Re: proposal: psql autocomplete for casting

От
Kyotaro HORIGUCHI
Дата:
At Thu, 3 Mar 2016 12:15:13 +0100, Pavel Stehule <pavel.stehule@gmail.com> wrote in
<CAFj8pRDB2PpESLxnwNDXmhvTS9VL0NMeAnUdv_hps9WzYwXLjw@mail.gmail.com>
pavel.stehule> 2016-03-03 12:06 GMT+01:00 Kyotaro HORIGUCHI <
> the requirement of space before is not good :( - It should be any different
> than operator chars. Not only space.
> 
> all other is perfect :)

Yeah, I fortunately agree with you:p

But the things are not so simple. readline can handle single
prefix characters but cannot not handle prefix strings.

The new diff adds ':' to WORD_BREAKS and adjusts related codes.
As far as I can see, colons are used only for variable prefix,
type casts and named parameter assignments in function
calls. This covers the first two and the last wouldn't be a
matter of tab-completion. This works as the following.

> =# select now()::t<tab>
> text                         trigger
> tid                          tsm_handler
> ...
> tinterval                    txid_snapshot
> =# select now()::te<tab>
> =# select now()::text 

As an inevitable side effect, this makes completion for ": :"
with types (which results in an syntax error) but I believe it
won't be a matter.

I'm quite unpleasant that the additional conditional expressions
use bare previous_words but found no good solution.

>   else if (previous_words_count >= 2 &&
>            previous_words[1][strlen(previous_words[1])-1] == ':' &&
>            TailMatches1(":"))

It is good if we could limit the candidate types by knowing the
operand type but it seems a bit complicated.

Some familiar type names won't come as candidates. They are
"int", "float", "decimal", "dec", which are known only to gram.y
but it does't seem to matter, too.

Thoughts? Opinions?

regards,

-- 
Kyotaro Horiguchi
NTT Open Source Software Center
diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c
index 5f27120..ab0e858 100644
--- a/src/bin/psql/tab-complete.c
+++ b/src/bin/psql/tab-complete.c
@@ -58,7 +58,7 @@ extern char *filename_completion_function();#endif/* word break characters */
-#define WORD_BREAKS        "\t\n@$><=;|&{() "
+#define WORD_BREAKS        "\t\n@$><=;:|&{() "/* * Since readline doesn't let us pass any state through to the tab
completion
@@ -1312,15 +1312,23 @@ psql_completion(const char *text, int start, int end)    if (text[0] == '\\')
COMPLETE_WITH_LIST_CS(backslash_commands);
+    /* If current word is a typecast, handle that case */
+    else if (previous_words_count >= 2 &&
+             previous_words[1][strlen(previous_words[1])-1] == ':' &&
+             TailMatches1(":"))
+        COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_datatypes, NULL);
+    /* If current word is a variable interpolation, handle that case */
-    else if (text[0] == ':' && text[1] != ':')
-    {
-        if (text[1] == '\'')
-            matches = complete_from_variables(text, ":'", "'", true);
-        else if (text[1] == '"')
-            matches = complete_from_variables(text, ":\"", "\"", true);
+    else if ((previous_words_count < 2 ||
+              previous_words[1][strlen(previous_words[1])-1] != ':') &&
+             TailMatches1(":"))
+    {
+        if (text[0] == '\'')
+            matches = complete_from_variables(text, "'", "'", true);
+        else if (text[0] == '"')
+            matches = complete_from_variables(text, "\"", "\"", true);        else
-            matches = complete_from_variables(text, ":", "", true);
+            matches = complete_from_variables(text, "", "", true);    }    /* If no previous word, suggest one of the
basicsql commands */ 

Re: proposal: psql autocomplete for casting

От
Pavel Stehule
Дата:


2016-03-04 5:29 GMT+01:00 Kyotaro HORIGUCHI <horiguchi.kyotaro@lab.ntt.co.jp>:
At Thu, 3 Mar 2016 12:15:13 +0100, Pavel Stehule <pavel.stehule@gmail.com> wrote in <CAFj8pRDB2PpESLxnwNDXmhvTS9VL0NMeAnUdv_hps9WzYwXLjw@mail.gmail.com>
pavel.stehule> 2016-03-03 12:06 GMT+01:00 Kyotaro HORIGUCHI <
> the requirement of space before is not good :( - It should be any different
> than operator chars. Not only space.
>
> all other is perfect :)

Yeah, I fortunately agree with you:p

But the things are not so simple. readline can handle single
prefix characters but cannot not handle prefix strings.

The new diff adds ':' to WORD_BREAKS and adjusts related codes.
As far as I can see, colons are used only for variable prefix,
type casts and named parameter assignments in function
calls. This covers the first two and the last wouldn't be a
matter of tab-completion. This works as the following.

> =# select now()::t<tab>
> text                         trigger
> tid                          tsm_handler
> ...
> tinterval                    txid_snapshot
> =# select now()::te<tab>
> =# select now()::text

As an inevitable side effect, this makes completion for ": :"
with types (which results in an syntax error) but I believe it
won't be a matter.

I'm quite unpleasant that the additional conditional expressions
use bare previous_words but found no good solution.

>   else if (previous_words_count >= 2 &&
>            previous_words[1][strlen(previous_words[1])-1] == ':' &&
>            TailMatches1(":"))

It is good if we could limit the candidate types by knowing the
operand type but it seems a bit complicated.

Some familiar type names won't come as candidates. They are
"int", "float", "decimal", "dec", which are known only to gram.y
but it does't seem to matter, too.

Thoughts? Opinions?

It works. I found only one issue with multi word named types

I have not any complete option for  select 1::timestamp with

maybe it is another limit of readline

Regards

Pavel


regards,

--
Kyotaro Horiguchi
NTT Open Source Software Center