On Sat, May 3, 2008 at 6:12 PM, Tom Lane <[EMAIL PROTECTED]> wrote: > > Peter Eisentraut <[EMAIL PROTECTED]> writes: > > Is there anything useful you would do with this information? Or would you > > just quote all listed words anyway?
Currently, yes, we just quote all listed words. > I think the practical application would be to avoid quoting unreserved > keywords, as pg_dump for instance already does. I doubt anyone would > bother distinguishing the different types of partially/wholly reserved > words. So maybe a boolean would be sufficient --- but I have nothing > against the R/T/C/U suggestion. > > A more radical alternative is just to omit unreserved words from the > view altogether. Well my thinking is that it costs nothing extra bar a dozen lines of code to include the info now in case it's useful in the future, if not for pgAdmin, then maybe for Lightning Admin or one of the other tools. If a need for it arises in the future and we haven't included it now we'll either want to add a second function or break compatibility both of which strike me as a lot more objectionable than doing it all now. Attached is an updated patch, giving the following output. The catdesc column can be translated. postgres=# select * from pg_get_keywords(); word | catcode | catdesc -------------------+---------+----------------------- abort | U | Unreserved all | R | Reserved bigint | C | Column name binary | T | Type or function name -- Dave Page EnterpriseDB UK: http://www.enterprisedb.com
Index: doc/src/sgml/func.sgml =================================================================== RCS file: /projects/cvsroot/pgsql/doc/src/sgml/func.sgml,v retrieving revision 1.434 diff -c -r1.434 func.sgml *** doc/src/sgml/func.sgml 28 Apr 2008 14:48:57 -0000 1.434 --- doc/src/sgml/func.sgml 3 May 2008 19:10:03 -0000 *************** *** 10874,10879 **** --- 10874,10885 ---- </row> <row> + <entry><literal><function>pg_get_keywords</function>()</literal></entry> + <entry><type>setof record</type></entry> + <entry>list of keywords and their categories</entry> + </row> + + <row> <entry><literal><function>pg_my_temp_schema</function>()</literal></entry> <entry><type>oid</type></entry> <entry>OID of session's temporary schema, or 0 if none</entry> *************** *** 11009,11014 **** --- 11015,11033 ---- </para> <indexterm> + <primary>pg_get_keywords</primary> + </indexterm> + + <para> + <function>pg_get_keywords</function> returns a set of records describing + the keywords recognized by the server. The <structfield>word</> column + contains the keyword, the <structfield>catcode</> column contains a + category code of 'U' for unknown, 'C' for column name, 'T' for type or + function name or 'U' for unreserved. The <structfield>catdesc</> + column contains a localised stribg describing the category. + </para> + + <indexterm> <primary>pg_my_temp_schema</primary> </indexterm> Index: src/backend/parser/keywords.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/parser/keywords.c,v retrieving revision 1.195 diff -c -r1.195 keywords.c *** src/backend/parser/keywords.c 27 Mar 2008 03:57:33 -0000 1.195 --- src/backend/parser/keywords.c 2 May 2008 19:32:40 -0000 *************** *** 38,44 **** * !!WARNING!!: This list must be sorted by ASCII name, because binary * search is used to locate entries. */ ! static const ScanKeyword ScanKeywords[] = { /* name, value, category */ {"abort", ABORT_P, UNRESERVED_KEYWORD}, {"absolute", ABSOLUTE_P, UNRESERVED_KEYWORD}, --- 38,44 ---- * !!WARNING!!: This list must be sorted by ASCII name, because binary * search is used to locate entries. */ ! const ScanKeyword ScanKeywords[] = { /* name, value, category */ {"abort", ABORT_P, UNRESERVED_KEYWORD}, {"absolute", ABSOLUTE_P, UNRESERVED_KEYWORD}, *************** *** 423,428 **** --- 423,431 ---- {"zone", ZONE, UNRESERVED_KEYWORD}, }; + /* End of ScanKeywords, for use elsewhere */ + const ScanKeyword *LastScanKeyword = endof(ScanKeywords); + /* * ScanKeywordLookup - see if a given word is a keyword * Index: src/backend/utils/adt/misc.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/utils/adt/misc.c,v retrieving revision 1.62 diff -c -r1.62 misc.c *** src/backend/utils/adt/misc.c 17 Apr 2008 20:56:41 -0000 1.62 --- src/backend/utils/adt/misc.c 3 May 2008 19:27:58 -0000 *************** *** 20,29 **** --- 20,31 ---- #include <math.h> #include "access/xact.h" + #include "catalog/pg_type.h" #include "catalog/pg_tablespace.h" #include "commands/dbcommands.h" #include "funcapi.h" #include "miscadmin.h" + #include "parser/keywords.h" #include "postmaster/syslogger.h" #include "storage/fd.h" #include "storage/pmsignal.h" *************** *** 322,324 **** --- 324,396 ---- PG_RETURN_VOID(); } + + /* Function to return the keywords list */ + extern const ScanKeyword ScanKeywords[]; + extern const ScanKeyword *LastScanKeyword; + + Datum + pg_get_keywords(PG_FUNCTION_ARGS) + { + FuncCallContext *funcctx; + + if (SRF_IS_FIRSTCALL()) + { + MemoryContext oldcontext; + TupleDesc tupdesc; + + funcctx = SRF_FIRSTCALL_INIT(); + oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); + + tupdesc = CreateTemplateTupleDesc(3, false); + TupleDescInitEntry(tupdesc, (AttrNumber) 1, "word", + TEXTOID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 2, "catcode", + CHAROID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 3, "catdesc", + TEXTOID, -1, 0); + + funcctx->attinmeta = TupleDescGetAttInMetadata(tupdesc); + + MemoryContextSwitchTo(oldcontext); + } + + funcctx = SRF_PERCALL_SETUP(); + + if (&ScanKeywords[funcctx->call_cntr] < LastScanKeyword) + { + char *values[3]; + HeapTuple tuple; + + values[0] = ScanKeywords[funcctx->call_cntr].name; + + switch (ScanKeywords[funcctx->call_cntr].category) + { + case UNRESERVED_KEYWORD: + values[1] = "U"; + values[2] = _("Unreserved"); + break; + case COL_NAME_KEYWORD: + values[1] = "C"; + values[2] = _("Column name"); + break; + case TYPE_FUNC_NAME_KEYWORD: + values[1] = "T"; + values[2] = _("Type or function name"); + break; + case RESERVED_KEYWORD: + values[1] = "R"; + values[2] = _("Reserved"); + break; + default: + values[1] = ""; + values[2] = _("Unknown"); + } + + tuple = BuildTupleFromCStrings(funcctx->attinmeta, values); + + SRF_RETURN_NEXT(funcctx, HeapTupleGetDatum(tuple)); + } + + SRF_RETURN_DONE(funcctx); + } + Index: src/include/catalog/pg_proc.h =================================================================== RCS file: /projects/cvsroot/pgsql/src/include/catalog/pg_proc.h,v retrieving revision 1.494 diff -c -r1.494 pg_proc.h *** src/include/catalog/pg_proc.h 29 Apr 2008 13:00:22 -0000 1.494 --- src/include/catalog/pg_proc.h 3 May 2008 19:07:32 -0000 *************** *** 3193,3198 **** --- 3193,3201 ---- DATA(insert OID = 2626 ( pg_sleep PGNSP PGUID 12 1 0 f f t f v 1 2278 "701" _null_ _null_ _null_ pg_sleep - _null_ _null_ )); DESCR("sleep for the specified time in seconds"); + DATA(insert OID = 2700 ( pg_get_keywords PGNSP PGUID 12 10 400 f f t t s 0 2249 "" "{25,18,25}" "{o,o,o}" "{word,catcode,catdesc}" pg_get_keywords - _null_ _null_ )); + DESCR("return keyword list"); + DATA(insert OID = 2971 ( text PGNSP PGUID 12 1 0 f f t f i 1 25 "16" _null_ _null_ _null_ booltext - _null_ _null_ )); DESCR("convert boolean to text");
-- Sent via pgsql-patches mailing list (pgsql-patches@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-patches