7
7
*
8
8
*
9
9
* IDENTIFICATION
10
- * $PostgreSQL: pgsql/src/backend/commands/foreigncmds.c,v 1.2 2008/12/20 09:40:56 heikki Exp $
10
+ * $PostgreSQL: pgsql/src/backend/commands/foreigncmds.c,v 1.3 2008/12/20 15:51:28 tgl Exp $
11
11
*
12
12
*-------------------------------------------------------------------------
13
13
*/
35
35
/*
36
36
* Convert a DefElem list to the text array format that is used in
37
37
* pg_foreign_data_wrapper, pg_foreign_server, and pg_user_mapping.
38
+ * Returns the array in the form of a Datum, or PointerGetDatum(NULL)
39
+ * if the list is empty.
38
40
*
39
41
* Note: The array is usually stored to database without further
40
42
* processing, hence any validation should be done before this
@@ -45,13 +47,13 @@ optionListToArray(List *options)
45
47
{
46
48
ArrayBuildState * astate = NULL ;
47
49
ListCell * cell ;
48
- text * t ;
49
50
50
- foreach (cell , options )
51
+ foreach (cell , options )
51
52
{
52
53
DefElem * def = lfirst (cell );
53
- const char * value = "" ;
54
+ const char * value ;
54
55
Size len ;
56
+ text * t ;
55
57
56
58
value = defGetString (def );
57
59
len = VARHDRSZ + strlen (def -> defname ) + 1 + strlen (value );
@@ -76,6 +78,9 @@ optionListToArray(List *options)
76
78
* The result is converted to array of text suitable for storing in
77
79
* options.
78
80
*
81
+ * Returns the array in the form of a Datum, or PointerGetDatum(NULL)
82
+ * if the list is empty.
83
+ *
79
84
* This is used by CREATE/ALTER of FOREIGN DATA WRAPPER/SERVER/USER
80
85
* MAPPING. In the ALTER cases, oldOptions is the current text array
81
86
* of options.
@@ -90,15 +95,15 @@ transformGenericOptions(Datum oldOptions,
90
95
List * resultOptions = untransformRelOptions (oldOptions );
91
96
ListCell * optcell ;
92
97
93
- foreach (optcell , optionDefList )
98
+ foreach (optcell , optionDefList )
94
99
{
100
+ OptionDefElem * od = lfirst (optcell );
95
101
ListCell * cell ;
96
102
ListCell * prev = NULL ;
97
- OptionDefElem * od = lfirst (optcell );
98
103
99
104
/*
100
105
* Find the element in resultOptions. We need this for
101
- * validation in all cases.
106
+ * validation in all cases. Also identify the previous element.
102
107
*/
103
108
foreach (cell , resultOptions )
104
109
{
@@ -190,7 +195,6 @@ AlterForeignDataWrapperOwner(const char *name, Oid newOwnerId)
190
195
HeapTuple tup ;
191
196
Relation rel ;
192
197
Oid fdwId ;
193
-
194
198
Form_pg_foreign_data_wrapper form ;
195
199
196
200
/* Must be a superuser to change a FDW owner */
@@ -345,7 +349,8 @@ CreateForeignDataWrapper(CreateFdwStmt *stmt)
345
349
*/
346
350
rel = heap_open (ForeignDataWrapperRelationId , RowExclusiveLock );
347
351
348
- MemSet (nulls , false, Natts_pg_foreign_data_wrapper );
352
+ memset (values , 0 , sizeof (values ));
353
+ memset (nulls , false, sizeof (nulls ));
349
354
350
355
values [Anum_pg_foreign_data_wrapper_fdwname - 1 ] =
351
356
DirectFunctionCall1 (namein , CStringGetDatum (stmt -> fdwname ));
@@ -359,7 +364,8 @@ CreateForeignDataWrapper(CreateFdwStmt *stmt)
359
364
*/
360
365
fdwlib = GetForeignDataWrapperLibrary (stmt -> library );
361
366
362
- fdwoptions = transformGenericOptions (0 , stmt -> options , FdwOpt , NULL ,
367
+ fdwoptions = transformGenericOptions (PointerGetDatum (NULL ), stmt -> options ,
368
+ FdwOpt , NULL ,
363
369
fdwlib -> validateOptionList );
364
370
365
371
if (PointerIsValid (DatumGetPointer (fdwoptions )))
@@ -447,6 +453,7 @@ AlterForeignDataWrapper(AlterFdwStmt *stmt)
447
453
tp ,
448
454
Anum_pg_foreign_data_wrapper_fdwlibrary ,
449
455
& isnull );
456
+ Assert (!isnull );
450
457
fdwlib = GetForeignDataWrapperLibrary (TextDatumGetCString (datum ));
451
458
}
452
459
@@ -460,13 +467,15 @@ AlterForeignDataWrapper(AlterFdwStmt *stmt)
460
467
tp ,
461
468
Anum_pg_foreign_data_wrapper_fdwoptions ,
462
469
& isnull );
470
+ if (isnull )
471
+ datum = PointerGetDatum (NULL );
463
472
464
473
/* Transform the options */
465
474
datum = transformGenericOptions (datum , stmt -> options , FdwOpt ,
466
475
NULL , fdwlib -> validateOptionList );
467
476
468
477
if (PointerIsValid (DatumGetPointer (datum )))
469
- repl_val [Anum_pg_foreign_data_wrapper_fdwoptions - 1 ] = ObjectIdGetDatum ( datum ) ;
478
+ repl_val [Anum_pg_foreign_data_wrapper_fdwoptions - 1 ] = datum ;
470
479
else
471
480
repl_null [Anum_pg_foreign_data_wrapper_fdwoptions - 1 ] = true;
472
481
@@ -603,7 +612,8 @@ CreateForeignServer(CreateForeignServerStmt *stmt)
603
612
*/
604
613
rel = heap_open (ForeignServerRelationId , RowExclusiveLock );
605
614
606
- MemSet (nulls , false, Natts_pg_foreign_server );
615
+ memset (values , 0 , sizeof (values ));
616
+ memset (nulls , false, sizeof (nulls ));
607
617
608
618
values [Anum_pg_foreign_server_srvname - 1 ] =
609
619
DirectFunctionCall1 (namein , CStringGetDatum (stmt -> servername ));
@@ -628,7 +638,8 @@ CreateForeignServer(CreateForeignServerStmt *stmt)
628
638
nulls [Anum_pg_foreign_server_srvacl - 1 ] = true;
629
639
630
640
/* Add server options */
631
- srvoptions = transformGenericOptions (0 , stmt -> options , ServerOpt , fdw ,
641
+ srvoptions = transformGenericOptions (PointerGetDatum (NULL ), stmt -> options ,
642
+ ServerOpt , fdw ,
632
643
fdw -> lib -> validateOptionList );
633
644
634
645
if (PointerIsValid (DatumGetPointer (srvoptions )))
@@ -722,6 +733,8 @@ AlterForeignServer(AlterForeignServerStmt *stmt)
722
733
tp ,
723
734
Anum_pg_foreign_server_srvoptions ,
724
735
& isnull );
736
+ if (isnull )
737
+ datum = PointerGetDatum (NULL );
725
738
726
739
/* Prepare the options array */
727
740
datum = transformGenericOptions (datum , stmt -> options , ServerOpt ,
@@ -868,13 +881,15 @@ CreateUserMapping(CreateUserMappingStmt *stmt)
868
881
*/
869
882
rel = heap_open (UserMappingRelationId , RowExclusiveLock );
870
883
871
- MemSet (nulls , false, Natts_pg_user_mapping );
884
+ memset (values , 0 , sizeof (values ));
885
+ memset (nulls , false, sizeof (nulls ));
872
886
873
887
values [Anum_pg_user_mapping_umuser - 1 ] = ObjectIdGetDatum (useId );
874
888
values [Anum_pg_user_mapping_umserver - 1 ] = ObjectIdGetDatum (srv -> serverid );
875
889
876
890
/* Add user options */
877
- useoptions = transformGenericOptions (0 , stmt -> options , UserMappingOpt ,
891
+ useoptions = transformGenericOptions (PointerGetDatum (NULL ), stmt -> options ,
892
+ UserMappingOpt ,
878
893
fdw , fdw -> lib -> validateOptionList );
879
894
880
895
if (PointerIsValid (DatumGetPointer (useoptions )))
@@ -931,12 +946,10 @@ AlterUserMapping(AlterUserMappingStmt *stmt)
931
946
ObjectIdGetDatum (srv -> serverid ),
932
947
0 , 0 );
933
948
if (!OidIsValid (umId ))
934
- {
935
949
ereport (ERROR ,
936
950
(errcode (ERRCODE_UNDEFINED_OBJECT ),
937
951
errmsg ("user mapping \"%s\" does not exist for the server" ,
938
952
MappingUserName (useId ))));
939
- }
940
953
941
954
/*
942
955
* Must be owner of the server to alter user mapping.
@@ -972,6 +985,8 @@ AlterUserMapping(AlterUserMappingStmt *stmt)
972
985
tp ,
973
986
Anum_pg_user_mapping_umoptions ,
974
987
& isnull );
988
+ if (isnull )
989
+ datum = PointerGetDatum (NULL );
975
990
976
991
/* Prepare the options array */
977
992
datum = transformGenericOptions (datum , stmt -> options , UserMappingOpt ,
0 commit comments