]> granicus.if.org Git - postgresql/commitdiff
Improved tab completion for views with triggers.
authorRobert Haas <rhaas@postgresql.org>
Tue, 14 Dec 2010 03:37:55 +0000 (22:37 -0500)
committerRobert Haas <rhaas@postgresql.org>
Tue, 14 Dec 2010 03:46:55 +0000 (22:46 -0500)
Allow INSERT INTO, UPDATE, and DELETE FROM to be completed with
either the name of a table (as before) or the name of a view with
an appropriate INSTEAD OF rule.

Along the way, allow CREATE TRIGGER to be completed with INSTEAD OF,
as well as BEFORE and AFTER.

David Fetter, reviewed by Itagaki Takahiro

src/bin/psql/tab-complete.c

index 4c468a858cefd84f9525d47538c50f68b8caf919..c88d671f40dab53c3836255852f191b377735176 100644 (file)
@@ -303,6 +303,57 @@ static const SchemaQuery Query_for_list_of_tables = {
        NULL
 };
 
+/* The bit masks for the following three functions come from
+ * src/include/catalog/pg_trigger.h.
+ */
+static const SchemaQuery Query_for_list_of_insertables = {
+       /* catname */
+       "pg_catalog.pg_class c",
+       /* selcondition */
+       "(c.relkind = 'r' OR (c.relkind = 'v' AND c.relhastriggers AND EXISTS "
+       "(SELECT 1 FROM pg_catalog.pg_trigger t WHERE t.tgrelid = c.oid AND t.tgtype & (1 << 2) <> 0)))",
+       /* viscondition */
+       "pg_catalog.pg_table_is_visible(c.oid)",
+       /* namespace */
+       "c.relnamespace",
+       /* result */
+       "pg_catalog.quote_ident(c.relname)",
+       /* qualresult */
+       NULL
+};
+
+static const SchemaQuery Query_for_list_of_deletables = {
+       /* catname */
+       "pg_catalog.pg_class c",
+       /* selcondition */
+       "(c.relkind = 'r' OR (c.relkind = 'v' AND c.relhastriggers AND EXISTS "
+       "(SELECT 1 FROM pg_catalog.pg_trigger t WHERE t.tgrelid = c.oid AND t.tgtype & (1 << 3) <> 0)))",
+       /* viscondition */
+       "pg_catalog.pg_table_is_visible(c.oid)",
+       /* namespace */
+       "c.relnamespace",
+       /* result */
+       "pg_catalog.quote_ident(c.relname)",
+       /* qualresult */
+       NULL
+};
+
+static const SchemaQuery Query_for_list_of_updatables = {
+       /* catname */
+       "pg_catalog.pg_class c",
+       /* selcondition */
+       "(c.relkind = 'r' OR (c.relkind = 'v' AND c.relhastriggers AND EXISTS "
+       "(SELECT 1 FROM pg_catalog.pg_trigger t WHERE t.tgrelid = c.oid AND t.tgtype & (1 << 4) <> 0)))",
+       /* viscondition */
+       "pg_catalog.pg_table_is_visible(c.oid)",
+       /* namespace */
+       "c.relnamespace",
+       /* result */
+       "pg_catalog.quote_ident(c.relname)",
+       /* qualresult */
+       NULL
+};
+
 static const SchemaQuery Query_for_list_of_tisv = {
        /* catname */
        "pg_catalog.pg_class c",
@@ -1655,7 +1706,7 @@ psql_completion(char *text, int start, int end)
                         pg_strcasecmp(prev2_wd, "TRIGGER") == 0)
        {
                static const char *const list_CREATETRIGGER[] =
-               {"BEFORE", "AFTER", NULL};
+               {"BEFORE", "AFTER", "INSTEAD OF", NULL};
 
                COMPLETE_WITH_LIST(list_CREATETRIGGER);
        }
@@ -1778,7 +1829,7 @@ psql_completion(char *text, int start, int end)
        /* Complete DELETE FROM with a list of tables */
        else if (pg_strcasecmp(prev2_wd, "DELETE") == 0 &&
                         pg_strcasecmp(prev_wd, "FROM") == 0)
-               COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
+               COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_deletables, NULL);
        /* Complete DELETE FROM <table> */
        else if (pg_strcasecmp(prev3_wd, "DELETE") == 0 &&
                         pg_strcasecmp(prev2_wd, "FROM") == 0)
@@ -2066,7 +2117,7 @@ psql_completion(char *text, int start, int end)
        /* Complete INSERT INTO with table names */
        else if (pg_strcasecmp(prev2_wd, "INSERT") == 0 &&
                         pg_strcasecmp(prev_wd, "INTO") == 0)
-               COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
+               COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_insertables, NULL);
        /* Complete "INSERT INTO <table> (" with attribute names */
        else if (pg_strcasecmp(prev4_wd, "INSERT") == 0 &&
                         pg_strcasecmp(prev3_wd, "INTO") == 0 &&
@@ -2423,7 +2474,7 @@ psql_completion(char *text, int start, int end)
 /* UPDATE */
        /* If prev. word is UPDATE suggest a list of tables */
        else if (pg_strcasecmp(prev_wd, "UPDATE") == 0)
-               COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
+               COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_updatables, NULL);
        /* Complete UPDATE <table> with "SET" */
        else if (pg_strcasecmp(prev2_wd, "UPDATE") == 0)
                COMPLETE_WITH_CONST("SET");