10
10
* Written by Peter Eisentraut <peter_e@gmx.net>.
11
11
*
12
12
* IDENTIFICATION
13
- * $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.139 2003/07/25 20:17:56 tgl Exp $
13
+ * $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.140 2003/07/27 04:35:53 momjian Exp $
14
14
*
15
15
*--------------------------------------------------------------------
16
16
*/
@@ -155,6 +155,47 @@ static char *timezone_string;
155
155
static char * XactIsoLevel_string ;
156
156
157
157
158
+ /*
159
+ * Used for pg_settings. Keep in sync with config_type enum above
160
+ */
161
+ static char * config_type_name [] =
162
+ {
163
+ "bool" ,
164
+ "integer" ,
165
+ "real" ,
166
+ "string"
167
+ };
168
+
169
+ /*
170
+ * Used for pg_settings. Keep in sync with GucContext enum in guc.h
171
+ */
172
+ static char * GucContextName [] =
173
+ {
174
+ "internal" ,
175
+ "postmaster" ,
176
+ "sighup" ,
177
+ "backend" ,
178
+ "super-user" ,
179
+ "user"
180
+ };
181
+
182
+ /*
183
+ * Used for pg_settings. Keep in sync with GucSource enum in guc.h
184
+ */
185
+ static char * GucSourceName [] =
186
+ {
187
+ "default" ,
188
+ "environment variable" ,
189
+ "configuration file" ,
190
+ "command line" ,
191
+ "database" ,
192
+ "user" ,
193
+ "client" ,
194
+ "override" ,
195
+ "session"
196
+ };
197
+
198
+
158
199
/* Macros for freeing malloc'd pointers only if appropriate to do so */
159
200
/* Some of these tests are probably redundant, but be safe ... */
160
201
#define SET_STRING_VARIABLE (rec , newval ) \
@@ -3323,23 +3364,102 @@ GetConfigOptionByName(const char *name, const char **varname)
3323
3364
* Return GUC variable value by variable number; optionally return canonical
3324
3365
* form of name. Return value is palloc'd.
3325
3366
*/
3326
- char *
3327
- GetConfigOptionByNum (int varnum , const char * * varname , bool * noshow )
3367
+ void
3368
+ GetConfigOptionByNum (int varnum , const char * * values , bool * noshow )
3328
3369
{
3329
- struct config_generic * conf ;
3370
+ char buffer [256 ];
3371
+ struct config_generic * conf ;
3330
3372
3331
3373
/* check requested variable number valid */
3332
3374
Assert ((varnum >= 0 ) && (varnum < num_guc_variables ));
3333
3375
3334
3376
conf = guc_variables [varnum ];
3335
3377
3336
- if (varname )
3337
- * varname = conf -> name ;
3338
-
3339
3378
if (noshow )
3340
3379
* noshow = (conf -> flags & GUC_NO_SHOW_ALL ) ? true : false;
3341
3380
3342
- return _ShowOption (conf );
3381
+ /* first get the generic attributes */
3382
+
3383
+ /* name */
3384
+ values [0 ] = conf -> name ;
3385
+
3386
+ /* setting : use _ShowOption in order to avoid duplicating the logic */
3387
+ values [1 ] = _ShowOption (conf );
3388
+
3389
+ /* context */
3390
+ values [2 ] = GucContextName [conf -> context ];
3391
+
3392
+ /* vartype */
3393
+ values [3 ] = config_type_name [conf -> vartype ];
3394
+
3395
+ /* source */
3396
+ values [4 ] = GucSourceName [conf -> source ];
3397
+
3398
+ /* now get the type specifc attributes */
3399
+ switch (conf -> vartype )
3400
+ {
3401
+ case PGC_BOOL :
3402
+ {
3403
+ /* min_val */
3404
+ values [5 ] = NULL ;
3405
+
3406
+ /* max_val */
3407
+ values [6 ] = NULL ;
3408
+ }
3409
+ break ;
3410
+
3411
+ case PGC_INT :
3412
+ {
3413
+ struct config_int * lconf = (struct config_int * ) conf ;
3414
+
3415
+ /* min_val */
3416
+ snprintf (buffer , sizeof (buffer ), "%d" , lconf -> min );
3417
+ values [5 ] = pstrdup (buffer );
3418
+
3419
+ /* max_val */
3420
+ snprintf (buffer , sizeof (buffer ), "%d" , lconf -> max );
3421
+ values [6 ] = pstrdup (buffer );
3422
+ }
3423
+ break ;
3424
+
3425
+ case PGC_REAL :
3426
+ {
3427
+ struct config_real * lconf = (struct config_real * ) conf ;
3428
+
3429
+ /* min_val */
3430
+ snprintf (buffer , sizeof (buffer ), "%g" , lconf -> min );
3431
+ values [5 ] = pstrdup (buffer );
3432
+
3433
+ /* max_val */
3434
+ snprintf (buffer , sizeof (buffer ), "%g" , lconf -> max );
3435
+ values [6 ] = pstrdup (buffer );
3436
+ }
3437
+ break ;
3438
+
3439
+ case PGC_STRING :
3440
+ {
3441
+ /* min_val */
3442
+ values [5 ] = NULL ;
3443
+
3444
+ /* max_val */
3445
+ values [6 ] = NULL ;
3446
+ }
3447
+ break ;
3448
+
3449
+ default :
3450
+ {
3451
+ /*
3452
+ * should never get here, but in case we do, set 'em to NULL
3453
+ */
3454
+
3455
+ /* min_val */
3456
+ values [5 ] = NULL ;
3457
+
3458
+ /* max_val */
3459
+ values [6 ] = NULL ;
3460
+ }
3461
+ break ;
3462
+ }
3343
3463
}
3344
3464
3345
3465
/*
@@ -3379,6 +3499,8 @@ show_config_by_name(PG_FUNCTION_ARGS)
3379
3499
* show_all_settings - equiv to SHOW ALL command but implemented as
3380
3500
* a Table Function.
3381
3501
*/
3502
+ #define NUM_PG_SETTINGS_ATTS 7
3503
+
3382
3504
Datum
3383
3505
show_all_settings (PG_FUNCTION_ARGS )
3384
3506
{
@@ -3402,12 +3524,25 @@ show_all_settings(PG_FUNCTION_ARGS)
3402
3524
*/
3403
3525
oldcontext = MemoryContextSwitchTo (funcctx -> multi_call_memory_ctx );
3404
3526
3405
- /* need a tuple descriptor representing two TEXT columns */
3406
- tupdesc = CreateTemplateTupleDesc (2 , false);
3527
+ /*
3528
+ * need a tuple descriptor representing NUM_PG_SETTINGS_ATTS columns
3529
+ * of the appropriate types
3530
+ */
3531
+ tupdesc = CreateTemplateTupleDesc (NUM_PG_SETTINGS_ATTS , false);
3407
3532
TupleDescInitEntry (tupdesc , (AttrNumber ) 1 , "name" ,
3408
3533
TEXTOID , -1 , 0 , false);
3409
3534
TupleDescInitEntry (tupdesc , (AttrNumber ) 2 , "setting" ,
3410
3535
TEXTOID , -1 , 0 , false);
3536
+ TupleDescInitEntry (tupdesc , (AttrNumber ) 3 , "context" ,
3537
+ TEXTOID , -1 , 0 , false);
3538
+ TupleDescInitEntry (tupdesc , (AttrNumber ) 4 , "vartype" ,
3539
+ TEXTOID , -1 , 0 , false);
3540
+ TupleDescInitEntry (tupdesc , (AttrNumber ) 5 , "source" ,
3541
+ TEXTOID , -1 , 0 , false);
3542
+ TupleDescInitEntry (tupdesc , (AttrNumber ) 6 , "min_val" ,
3543
+ TEXTOID , -1 , 0 , false);
3544
+ TupleDescInitEntry (tupdesc , (AttrNumber ) 7 , "max_val" ,
3545
+ TEXTOID , -1 , 0 , false);
3411
3546
3412
3547
/* allocate a slot for a tuple with this tupdesc */
3413
3548
slot = TupleDescGetSlot (tupdesc );
@@ -3438,9 +3573,7 @@ show_all_settings(PG_FUNCTION_ARGS)
3438
3573
3439
3574
if (call_cntr < max_calls ) /* do when there is more left to send */
3440
3575
{
3441
- char * values [2 ];
3442
- char * varname ;
3443
- char * varval ;
3576
+ char * values [NUM_PG_SETTINGS_ATTS ];
3444
3577
bool noshow ;
3445
3578
HeapTuple tuple ;
3446
3579
Datum result ;
@@ -3450,15 +3583,9 @@ show_all_settings(PG_FUNCTION_ARGS)
3450
3583
*/
3451
3584
do
3452
3585
{
3453
- varval = GetConfigOptionByNum (call_cntr ,
3454
- (const char * * ) & varname ,
3455
- & noshow );
3586
+ GetConfigOptionByNum (call_cntr , (const char * * ) values , & noshow );
3456
3587
if (noshow )
3457
3588
{
3458
- /* varval is a palloc'd copy, so free it */
3459
- if (varval != NULL )
3460
- pfree (varval );
3461
-
3462
3589
/* bump the counter and get the next config setting */
3463
3590
call_cntr = ++ funcctx -> call_cntr ;
3464
3591
@@ -3468,24 +3595,12 @@ show_all_settings(PG_FUNCTION_ARGS)
3468
3595
}
3469
3596
} while (noshow );
3470
3597
3471
- /*
3472
- * Prepare a values array for storage in our slot. This should be
3473
- * an array of C strings which will be processed later by the
3474
- * appropriate "in" functions.
3475
- */
3476
- values [0 ] = varname ;
3477
- values [1 ] = varval ;
3478
-
3479
3598
/* build a tuple */
3480
3599
tuple = BuildTupleFromCStrings (attinmeta , values );
3481
3600
3482
3601
/* make the tuple into a datum */
3483
3602
result = TupleGetDatum (slot , tuple );
3484
3603
3485
- /* Clean up */
3486
- if (varval != NULL )
3487
- pfree (varval );
3488
-
3489
3604
SRF_RETURN_NEXT (funcctx , result );
3490
3605
}
3491
3606
else
0 commit comments