@@ -669,6 +669,7 @@ create_single_partition_internal(Oid parent_relid,
669
669
List * create_stmts ;
670
670
ListCell * lc ;
671
671
672
+ /* Current user and security context */
672
673
Oid save_userid ;
673
674
int save_sec_context ;
674
675
bool need_priv_escalation = !superuser (); /* we might be a SU */
@@ -861,21 +862,29 @@ create_table_using_stmt(CreateStmt *create_stmt, Oid relowner)
861
862
static void
862
863
copy_acl_privileges (Oid parent_relid , Oid partition_relid )
863
864
{
864
- Relation pg_class_rel ;
865
+ Relation pg_class_rel ,
866
+ pg_attribute_rel ;
865
867
866
- TupleDesc pg_class_desc ;
868
+ TupleDesc pg_class_desc ,
869
+ pg_attribute_desc ;
867
870
868
871
HeapTuple htup ;
869
-
870
- ScanKeyData skey ;
872
+ ScanKeyData skey [2 ];
871
873
SysScanDesc scan ;
872
874
873
875
Datum acl_datum ;
874
876
bool acl_null ;
875
877
878
+ Snapshot snapshot ;
879
+
876
880
pg_class_rel = heap_open (RelationRelationId , RowExclusiveLock );
881
+ pg_attribute_rel = heap_open (AttributeRelationId , RowExclusiveLock );
882
+
883
+ /* Get most recent snapshot */
884
+ snapshot = RegisterSnapshot (GetLatestSnapshot ());
877
885
878
886
pg_class_desc = RelationGetDescr (pg_class_rel );
887
+ pg_attribute_desc = RelationGetDescr (pg_attribute_rel );
879
888
880
889
htup = SearchSysCache1 (RELOID , ObjectIdGetDatum (parent_relid ));
881
890
if (!HeapTupleIsValid (htup ))
@@ -886,21 +895,25 @@ copy_acl_privileges(Oid parent_relid, Oid partition_relid)
886
895
887
896
/* Copy datum if it's not NULL */
888
897
if (!acl_null )
889
- acl_datum = datumCopy (acl_datum ,
890
- pg_class_desc -> attrs [Anum_pg_class_relacl - 1 ]-> attbyval ,
891
- pg_class_desc -> attrs [Anum_pg_class_relacl - 1 ]-> attlen );
898
+ {
899
+ Form_pg_attribute acl_column ;
900
+
901
+ acl_column = pg_class_desc -> attrs [Anum_pg_class_relacl - 1 ];
902
+
903
+ acl_datum = datumCopy (acl_datum , acl_column -> attbyval , acl_column -> attlen );
904
+ }
892
905
893
906
/* Release 'htup' */
894
907
ReleaseSysCache (htup );
895
908
896
909
/* Search for 'partition_relid' */
897
- ScanKeyInit (& skey ,
910
+ ScanKeyInit (& skey [ 0 ] ,
898
911
ObjectIdAttributeNumber ,
899
912
BTEqualStrategyNumber , F_OIDEQ ,
900
913
ObjectIdGetDatum (partition_relid ));
901
914
902
- scan = systable_beginscan (pg_class_rel , ClassOidIndexId , true,
903
- GetLatestSnapshot (), 1 , & skey );
915
+ scan = systable_beginscan (pg_class_rel , ClassOidIndexId ,
916
+ true, snapshot , 1 , skey );
904
917
905
918
/* There should be exactly one tuple (our child) */
906
919
if (HeapTupleIsValid (htup = systable_getnext (scan )))
@@ -918,8 +931,7 @@ copy_acl_privileges(Oid parent_relid, Oid partition_relid)
918
931
replaces [Anum_pg_class_relacl - 1 ] = true;
919
932
920
933
/* Build new tuple with parent's ACL */
921
- htup = heap_modify_tuple (htup , RelationGetDescr (pg_class_rel ),
922
- values , nulls , replaces );
934
+ htup = heap_modify_tuple (htup , pg_class_desc , values , nulls , replaces );
923
935
924
936
/* Update child's tuple */
925
937
simple_heap_update (pg_class_rel , & iptr , htup );
@@ -930,7 +942,106 @@ copy_acl_privileges(Oid parent_relid, Oid partition_relid)
930
942
931
943
systable_endscan (scan );
932
944
945
+
946
+ /* Search for 'parent_relid's columns */
947
+ ScanKeyInit (& skey [0 ],
948
+ Anum_pg_attribute_attrelid ,
949
+ BTEqualStrategyNumber , F_OIDEQ ,
950
+ ObjectIdGetDatum (parent_relid ));
951
+
952
+ /* Consider only user-defined columns (>0) */
953
+ ScanKeyInit (& skey [1 ],
954
+ Anum_pg_attribute_attnum ,
955
+ BTEqualStrategyNumber , F_INT2GT ,
956
+ Int16GetDatum (InvalidAttrNumber ));
957
+
958
+ scan = systable_beginscan (pg_attribute_rel ,
959
+ AttributeRelidNumIndexId ,
960
+ true, snapshot , 2 , skey );
961
+
962
+ /* Go through the list of parent's columns */
963
+ while (HeapTupleIsValid (htup = systable_getnext (scan )))
964
+ {
965
+ ScanKeyData subskey [2 ];
966
+ SysScanDesc subscan ;
967
+ HeapTuple subhtup ;
968
+
969
+ AttrNumber cur_attnum ;
970
+ bool cur_attnum_null ;
971
+
972
+ /* Get parent column's ACL */
973
+ acl_datum = heap_getattr (htup , Anum_pg_attribute_attacl ,
974
+ pg_attribute_desc , & acl_null );
975
+
976
+ /* Copy datum if it's not NULL */
977
+ if (!acl_null )
978
+ {
979
+ Form_pg_attribute acl_column ;
980
+
981
+ acl_column = pg_attribute_desc -> attrs [Anum_pg_attribute_attacl - 1 ];
982
+
983
+ acl_datum = datumCopy (acl_datum ,
984
+ acl_column -> attbyval ,
985
+ acl_column -> attlen );
986
+ }
987
+
988
+ /* Fetch number of current column */
989
+ cur_attnum = DatumGetInt16 (heap_getattr (htup , Anum_pg_attribute_attnum ,
990
+ pg_attribute_desc , & cur_attnum_null ));
991
+ Assert (cur_attnum_null == false); /* must not be NULL! */
992
+
993
+ /* Search for 'partition_relid' */
994
+ ScanKeyInit (& subskey [0 ],
995
+ Anum_pg_attribute_attrelid ,
996
+ BTEqualStrategyNumber , F_OIDEQ ,
997
+ ObjectIdGetDatum (partition_relid ));
998
+
999
+ /* Search for 'partition_relid's columns */
1000
+ ScanKeyInit (& subskey [1 ],
1001
+ Anum_pg_attribute_attnum ,
1002
+ BTEqualStrategyNumber , F_INT2EQ ,
1003
+ Int16GetDatum (cur_attnum ));
1004
+
1005
+ subscan = systable_beginscan (pg_attribute_rel ,
1006
+ AttributeRelidNumIndexId ,
1007
+ true, snapshot , 2 , subskey );
1008
+
1009
+ /* There should be exactly one tuple (our child's column) */
1010
+ if (HeapTupleIsValid (subhtup = systable_getnext (subscan )))
1011
+ {
1012
+ ItemPointerData iptr ;
1013
+ Datum values [Natts_pg_attribute ] = { (Datum ) 0 };
1014
+ bool nulls [Natts_pg_attribute ] = { false };
1015
+ bool replaces [Natts_pg_attribute ] = { false };
1016
+
1017
+ /* Copy ItemPointer of this tuple */
1018
+ iptr = subhtup -> t_self ;
1019
+
1020
+ values [Anum_pg_attribute_attacl - 1 ] = acl_datum ; /* ACL array */
1021
+ nulls [Anum_pg_attribute_attacl - 1 ] = acl_null ; /* do we have ACL? */
1022
+ replaces [Anum_pg_attribute_attacl - 1 ] = true;
1023
+
1024
+ /* Build new tuple with parent's ACL */
1025
+ subhtup = heap_modify_tuple (subhtup , pg_attribute_desc ,
1026
+ values , nulls , replaces );
1027
+
1028
+ /* Update child's tuple */
1029
+ simple_heap_update (pg_attribute_rel , & iptr , subhtup );
1030
+
1031
+ /* Don't forget to update indexes */
1032
+ CatalogUpdateIndexes (pg_attribute_rel , subhtup );
1033
+ }
1034
+
1035
+ systable_endscan (subscan );
1036
+ }
1037
+
1038
+ systable_endscan (scan );
1039
+
1040
+ /* Don't forget to free snapshot */
1041
+ UnregisterSnapshot (snapshot );
1042
+
933
1043
heap_close (pg_class_rel , RowExclusiveLock );
1044
+ heap_close (pg_attribute_rel , RowExclusiveLock );
934
1045
}
935
1046
936
1047
/* Copy foreign keys of parent table */
0 commit comments