|
8 | 8 | *
|
9 | 9 | *
|
10 | 10 | * IDENTIFICATION
|
11 |
| - * $PostgreSQL: pgsql/src/backend/utils/adt/misc.c,v 1.62 2008/04/17 20:56:41 momjian Exp $ |
| 11 | + * $PostgreSQL: pgsql/src/backend/utils/adt/misc.c,v 1.63 2008/07/03 20:58:46 tgl Exp $ |
12 | 12 | *
|
13 | 13 | *-------------------------------------------------------------------------
|
14 | 14 | */
|
|
20 | 20 | #include<math.h>
|
21 | 21 |
|
22 | 22 | #include"access/xact.h"
|
| 23 | +#include"catalog/pg_type.h" |
23 | 24 | #include"catalog/pg_tablespace.h"
|
24 | 25 | #include"commands/dbcommands.h"
|
25 | 26 | #include"funcapi.h"
|
26 | 27 | #include"miscadmin.h"
|
| 28 | +#include"parser/keywords.h" |
27 | 29 | #include"postmaster/syslogger.h"
|
28 | 30 | #include"storage/fd.h"
|
29 | 31 | #include"storage/pmsignal.h"
|
@@ -322,3 +324,72 @@ pg_sleep(PG_FUNCTION_ARGS)
|
322 | 324 |
|
323 | 325 | PG_RETURN_VOID();
|
324 | 326 | }
|
| 327 | + |
| 328 | +/* Function to return the list of grammar keywords */ |
| 329 | +Datum |
| 330 | +pg_get_keywords(PG_FUNCTION_ARGS) |
| 331 | +{ |
| 332 | +FuncCallContext*funcctx; |
| 333 | + |
| 334 | +if (SRF_IS_FIRSTCALL()) |
| 335 | +{ |
| 336 | +MemoryContextoldcontext; |
| 337 | +TupleDesctupdesc; |
| 338 | + |
| 339 | +funcctx=SRF_FIRSTCALL_INIT(); |
| 340 | +oldcontext=MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); |
| 341 | + |
| 342 | +tupdesc=CreateTemplateTupleDesc(3, false); |
| 343 | +TupleDescInitEntry(tupdesc, (AttrNumber)1,"word", |
| 344 | +TEXTOID,-1,0); |
| 345 | +TupleDescInitEntry(tupdesc, (AttrNumber)2,"catcode", |
| 346 | +CHAROID,-1,0); |
| 347 | +TupleDescInitEntry(tupdesc, (AttrNumber)3,"catdesc", |
| 348 | +TEXTOID,-1,0); |
| 349 | + |
| 350 | +funcctx->attinmeta=TupleDescGetAttInMetadata(tupdesc); |
| 351 | + |
| 352 | +MemoryContextSwitchTo(oldcontext); |
| 353 | +} |
| 354 | + |
| 355 | +funcctx=SRF_PERCALL_SETUP(); |
| 356 | + |
| 357 | +if (&ScanKeywords[funcctx->call_cntr]<LastScanKeyword) |
| 358 | +{ |
| 359 | +char*values[3]; |
| 360 | +HeapTupletuple; |
| 361 | + |
| 362 | +/* cast-away-const is ugly but alternatives aren't much better */ |
| 363 | +values[0]= (char*)ScanKeywords[funcctx->call_cntr].name; |
| 364 | + |
| 365 | +switch (ScanKeywords[funcctx->call_cntr].category) |
| 366 | +{ |
| 367 | +caseUNRESERVED_KEYWORD: |
| 368 | +values[1]="U"; |
| 369 | +values[2]=_("Unreserved"); |
| 370 | +break; |
| 371 | +caseCOL_NAME_KEYWORD: |
| 372 | +values[1]="C"; |
| 373 | +values[2]=_("Column name"); |
| 374 | +break; |
| 375 | +caseTYPE_FUNC_NAME_KEYWORD: |
| 376 | +values[1]="T"; |
| 377 | +values[2]=_("Type or function name"); |
| 378 | +break; |
| 379 | +caseRESERVED_KEYWORD: |
| 380 | +values[1]="R"; |
| 381 | +values[2]=_("Reserved"); |
| 382 | +break; |
| 383 | +default:/* shouldn't be possible */ |
| 384 | +values[1]=NULL; |
| 385 | +values[2]=NULL; |
| 386 | +break; |
| 387 | +} |
| 388 | + |
| 389 | +tuple=BuildTupleFromCStrings(funcctx->attinmeta,values); |
| 390 | + |
| 391 | +SRF_RETURN_NEXT(funcctx,HeapTupleGetDatum(tuple)); |
| 392 | +} |
| 393 | + |
| 394 | +SRF_RETURN_DONE(funcctx); |
| 395 | +} |