aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2008-07-03 20:58:47 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2008-07-03 20:58:47 +0000
commitc63147d6f0e86d96ffb315147f36af613a35c2ce (patch)
treeab767c9fa14153d7fafd45d7fa1350d50265ab89
parente3d9dceef62e072cf9a433ae6c74a1c5a10d94d3 (diff)
downloadpostgresql-c63147d6f0e86d96ffb315147f36af613a35c2ce.tar.gz
postgresql-c63147d6f0e86d96ffb315147f36af613a35c2ce.zip
Add a function pg_get_keywords() to let clients find out the set of keywords
known to the SQL parser. Dave Page
-rw-r--r--doc/src/sgml/func.sgml21
-rw-r--r--src/backend/parser/keywords.c7
-rw-r--r--src/backend/utils/adt/misc.c73
-rw-r--r--src/include/catalog/catversion.h4
-rw-r--r--src/include/catalog/pg_proc.h5
-rw-r--r--src/include/parser/keywords.h5
-rw-r--r--src/include/utils/builtins.h3
7 files changed, 109 insertions, 9 deletions
diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index 48cb4f6c2b6..d3529f560e3 100644
--- a/doc/src/sgml/func.sgml
+++ b/doc/src/sgml/func.sgml
@@ -1,4 +1,4 @@
-<!-- $PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.437 2008/05/19 18:08:15 tgl Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.438 2008/07/03 20:58:46 tgl Exp $ -->
<chapter id="functions">
<title>Functions and Operators</title>
@@ -11485,6 +11485,10 @@ SELECT pg_type_is_visible('myschema.widget'::regtype);
</indexterm>
<indexterm>
+ <primary>pg_get_keywords</primary>
+ </indexterm>
+
+ <indexterm>
<primary>pg_get_viewdef</primary>
</indexterm>
@@ -11539,6 +11543,11 @@ SELECT pg_type_is_visible('myschema.widget'::regtype);
<entry>get SQL name of a data type</entry>
</row>
<row>
+ <entry><literal><function>pg_get_keywords</function>()</literal></entry>
+ <entry><type>setof record</type></entry>
+ <entry>get list of SQL keywords and their categories</entry>
+ </row>
+ <row>
<entry><literal><function>pg_get_constraintdef</function>(<parameter>constraint_oid</parameter>)</literal></entry>
<entry><type>text</type></entry>
<entry>get definition of a constraint</entry>
@@ -11634,6 +11643,16 @@ SELECT pg_type_is_visible('myschema.widget'::regtype);
</para>
<para>
+ <function>pg_get_keywords</function> returns a set of records describing
+ the SQL keywords recognized by the server. The <structfield>word</> column
+ contains the keyword. The <structfield>catcode</> column contains a
+ category code: <literal>U</> for unreserved, <literal>C</> for column name,
+ <literal>T</> for type or function name, or <literal>R</> for reserved.
+ The <structfield>catdesc</> column contains a possibly-localized string
+ describing the category.
+ </para>
+
+ <para>
<function>pg_get_constraintdef</function>,
<function>pg_get_indexdef</function>, <function>pg_get_ruledef</function>,
and <function>pg_get_triggerdef</function>, respectively reconstruct the
diff --git a/src/backend/parser/keywords.c b/src/backend/parser/keywords.c
index edb76596623..43013e1e772 100644
--- a/src/backend/parser/keywords.c
+++ b/src/backend/parser/keywords.c
@@ -11,7 +11,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/parser/keywords.c,v 1.197 2008/05/21 19:51:01 meskes Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/keywords.c,v 1.198 2008/07/03 20:58:46 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -41,7 +41,7 @@
* !!WARNING!!: This list must be sorted by ASCII name, because binary
* search is used to locate entries.
*/
-static const ScanKeyword ScanKeywords[] = {
+const ScanKeyword ScanKeywords[] = {
/* name, value, category */
{"abort", ABORT_P, UNRESERVED_KEYWORD},
{"absolute", ABSOLUTE_P, UNRESERVED_KEYWORD},
@@ -428,6 +428,9 @@ static const ScanKeyword ScanKeywords[] = {
{"zone", ZONE, UNRESERVED_KEYWORD},
};
+/* End of ScanKeywords, for use elsewhere */
+const ScanKeyword *LastScanKeyword = endof(ScanKeywords);
+
/*
* ScanKeywordLookup - see if a given word is a keyword
*
diff --git a/src/backend/utils/adt/misc.c b/src/backend/utils/adt/misc.c
index f99a07a9998..b48c004527c 100644
--- a/src/backend/utils/adt/misc.c
+++ b/src/backend/utils/adt/misc.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/adt/misc.c,v 1.62 2008/04/17 20:56:41 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/misc.c,v 1.63 2008/07/03 20:58:46 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -20,10 +20,12 @@
#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,3 +324,72 @@ pg_sleep(PG_FUNCTION_ARGS)
PG_RETURN_VOID();
}
+
+/* Function to return the list of grammar keywords */
+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;
+
+ /* cast-away-const is ugly but alternatives aren't much better */
+ values[0] = (char *) 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: /* shouldn't be possible */
+ values[1] = NULL;
+ values[2] = NULL;
+ break;
+ }
+
+ tuple = BuildTupleFromCStrings(funcctx->attinmeta, values);
+
+ SRF_RETURN_NEXT(funcctx, HeapTupleGetDatum(tuple));
+ }
+
+ SRF_RETURN_DONE(funcctx);
+}
diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h
index a49beccd54f..e7ba550c484 100644
--- a/src/include/catalog/catversion.h
+++ b/src/include/catalog/catversion.h
@@ -37,7 +37,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.464 2008/06/24 17:58:27 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.465 2008/07/03 20:58:46 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -53,6 +53,6 @@
*/
/* yyyymmddN */
-#define CATALOG_VERSION_NO 200806241
+#define CATALOG_VERSION_NO 200807031
#endif
diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h
index dbe79102822..09700e8f43a 100644
--- a/src/include/catalog/pg_proc.h
+++ b/src/include/catalog/pg_proc.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.503 2008/06/17 19:10:56 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.504 2008/07/03 20:58:46 tgl Exp $
*
* NOTES
* The script catalog/genbki.sh reads this file and generates .bki
@@ -2288,6 +2288,9 @@ DESCR("deparse an encoded expression");
DATA(insert OID = 1665 ( pg_get_serial_sequence PGNSP PGUID 12 1 0 f f t f s 2 25 "25 25" _null_ _null_ _null_ pg_get_serial_sequence - _null_ _null_ ));
DESCR("name of sequence for a serial column");
+DATA(insert OID = 1686 ( 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("list of SQL keywords");
+
/* Generic referential integrity constraint triggers */
DATA(insert OID = 1644 ( RI_FKey_check_ins PGNSP PGUID 12 1 0 f f t f v 0 2279 "" _null_ _null_ _null_ RI_FKey_check_ins - _null_ _null_ ));
diff --git a/src/include/parser/keywords.h b/src/include/parser/keywords.h
index 717e20e7df4..2da7fd3da9e 100644
--- a/src/include/parser/keywords.h
+++ b/src/include/parser/keywords.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/parser/keywords.h,v 1.24 2008/01/01 19:45:58 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/parser/keywords.h,v 1.25 2008/07/03 20:58:46 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -28,6 +28,9 @@ typedef struct ScanKeyword
int16 category; /* see codes above */
} ScanKeyword;
+extern const ScanKeyword ScanKeywords[];
+extern const ScanKeyword *LastScanKeyword;
+
extern const ScanKeyword *ScanKeywordLookup(const char *text);
#endif /* KEYWORDS_H */
diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h
index c34ee7aa904..2abbe667891 100644
--- a/src/include/utils/builtins.h
+++ b/src/include/utils/builtins.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/utils/builtins.h,v 1.317 2008/06/17 19:10:56 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/utils/builtins.h,v 1.318 2008/07/03 20:58:47 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -411,6 +411,7 @@ extern Datum pg_reload_conf(PG_FUNCTION_ARGS);
extern Datum pg_tablespace_databases(PG_FUNCTION_ARGS);
extern Datum pg_rotate_logfile(PG_FUNCTION_ARGS);
extern Datum pg_sleep(PG_FUNCTION_ARGS);
+extern Datum pg_get_keywords(PG_FUNCTION_ARGS);
/* oid.c */
extern Datum oidin(PG_FUNCTION_ARGS);