00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "postgres.h"
00012
00013 #include "access/genam.h"
00014 #include "access/heapam.h"
00015 #include "access/htup_details.h"
00016 #include "catalog/indexing.h"
00017 #include "catalog/objectaccess.h"
00018 #include "catalog/pg_db_role_setting.h"
00019 #include "utils/fmgroids.h"
00020 #include "utils/rel.h"
00021 #include "utils/tqual.h"
00022
00023 void
00024 AlterSetting(Oid databaseid, Oid roleid, VariableSetStmt *setstmt)
00025 {
00026 char *valuestr;
00027 HeapTuple tuple;
00028 Relation rel;
00029 ScanKeyData scankey[2];
00030 SysScanDesc scan;
00031
00032 valuestr = ExtractSetVariableArgs(setstmt);
00033
00034
00035
00036 rel = heap_open(DbRoleSettingRelationId, RowExclusiveLock);
00037 ScanKeyInit(&scankey[0],
00038 Anum_pg_db_role_setting_setdatabase,
00039 BTEqualStrategyNumber, F_OIDEQ,
00040 ObjectIdGetDatum(databaseid));
00041 ScanKeyInit(&scankey[1],
00042 Anum_pg_db_role_setting_setrole,
00043 BTEqualStrategyNumber, F_OIDEQ,
00044 ObjectIdGetDatum(roleid));
00045 scan = systable_beginscan(rel, DbRoleSettingDatidRolidIndexId, true,
00046 SnapshotNow, 2, scankey);
00047 tuple = systable_getnext(scan);
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061 if (setstmt->kind == VAR_RESET_ALL)
00062 {
00063 if (HeapTupleIsValid(tuple))
00064 {
00065 ArrayType *new = NULL;
00066 Datum datum;
00067 bool isnull;
00068
00069 datum = heap_getattr(tuple, Anum_pg_db_role_setting_setconfig,
00070 RelationGetDescr(rel), &isnull);
00071
00072 if (!isnull)
00073 new = GUCArrayReset(DatumGetArrayTypeP(datum));
00074
00075 if (new)
00076 {
00077 Datum repl_val[Natts_pg_db_role_setting];
00078 bool repl_null[Natts_pg_db_role_setting];
00079 bool repl_repl[Natts_pg_db_role_setting];
00080 HeapTuple newtuple;
00081
00082 memset(repl_repl, false, sizeof(repl_repl));
00083
00084 repl_val[Anum_pg_db_role_setting_setconfig - 1] =
00085 PointerGetDatum(new);
00086 repl_repl[Anum_pg_db_role_setting_setconfig - 1] = true;
00087 repl_null[Anum_pg_db_role_setting_setconfig - 1] = false;
00088
00089 newtuple = heap_modify_tuple(tuple, RelationGetDescr(rel),
00090 repl_val, repl_null, repl_repl);
00091 simple_heap_update(rel, &tuple->t_self, newtuple);
00092
00093
00094 CatalogUpdateIndexes(rel, newtuple);
00095 }
00096 else
00097 simple_heap_delete(rel, &tuple->t_self);
00098 }
00099 }
00100 else if (HeapTupleIsValid(tuple))
00101 {
00102 Datum repl_val[Natts_pg_db_role_setting];
00103 bool repl_null[Natts_pg_db_role_setting];
00104 bool repl_repl[Natts_pg_db_role_setting];
00105 HeapTuple newtuple;
00106 Datum datum;
00107 bool isnull;
00108 ArrayType *a;
00109
00110 memset(repl_repl, false, sizeof(repl_repl));
00111 repl_repl[Anum_pg_db_role_setting_setconfig - 1] = true;
00112 repl_null[Anum_pg_db_role_setting_setconfig - 1] = false;
00113
00114
00115 datum = heap_getattr(tuple, Anum_pg_db_role_setting_setconfig,
00116 RelationGetDescr(rel), &isnull);
00117 a = isnull ? NULL : DatumGetArrayTypeP(datum);
00118
00119
00120 if (valuestr)
00121 a = GUCArrayAdd(a, setstmt->name, valuestr);
00122 else
00123 a = GUCArrayDelete(a, setstmt->name);
00124
00125 if (a)
00126 {
00127 repl_val[Anum_pg_db_role_setting_setconfig - 1] =
00128 PointerGetDatum(a);
00129
00130 newtuple = heap_modify_tuple(tuple, RelationGetDescr(rel),
00131 repl_val, repl_null, repl_repl);
00132 simple_heap_update(rel, &tuple->t_self, newtuple);
00133
00134
00135 CatalogUpdateIndexes(rel, newtuple);
00136 }
00137 else
00138 simple_heap_delete(rel, &tuple->t_self);
00139 }
00140 else if (valuestr)
00141 {
00142
00143 HeapTuple newtuple;
00144 Datum values[Natts_pg_db_role_setting];
00145 bool nulls[Natts_pg_db_role_setting];
00146 ArrayType *a;
00147
00148 memset(nulls, false, sizeof(nulls));
00149
00150 a = GUCArrayAdd(NULL, setstmt->name, valuestr);
00151
00152 values[Anum_pg_db_role_setting_setdatabase - 1] =
00153 ObjectIdGetDatum(databaseid);
00154 values[Anum_pg_db_role_setting_setrole - 1] = ObjectIdGetDatum(roleid);
00155 values[Anum_pg_db_role_setting_setconfig - 1] = PointerGetDatum(a);
00156 newtuple = heap_form_tuple(RelationGetDescr(rel), values, nulls);
00157
00158 simple_heap_insert(rel, newtuple);
00159
00160
00161 CatalogUpdateIndexes(rel, newtuple);
00162 }
00163
00164 InvokeObjectPostAlterHookArg(DbRoleSettingRelationId,
00165 databaseid, 0, roleid, false);
00166
00167 systable_endscan(scan);
00168
00169
00170 heap_close(rel, NoLock);
00171 }
00172
00173
00174
00175
00176
00177
00178 void
00179 DropSetting(Oid databaseid, Oid roleid)
00180 {
00181 Relation relsetting;
00182 HeapScanDesc scan;
00183 ScanKeyData keys[2];
00184 HeapTuple tup;
00185 int numkeys = 0;
00186
00187 relsetting = heap_open(DbRoleSettingRelationId, RowExclusiveLock);
00188
00189 if (OidIsValid(databaseid))
00190 {
00191 ScanKeyInit(&keys[numkeys],
00192 Anum_pg_db_role_setting_setdatabase,
00193 BTEqualStrategyNumber,
00194 F_OIDEQ,
00195 ObjectIdGetDatum(databaseid));
00196 numkeys++;
00197 }
00198 if (OidIsValid(roleid))
00199 {
00200 ScanKeyInit(&keys[numkeys],
00201 Anum_pg_db_role_setting_setrole,
00202 BTEqualStrategyNumber,
00203 F_OIDEQ,
00204 ObjectIdGetDatum(roleid));
00205 numkeys++;
00206 }
00207
00208 scan = heap_beginscan(relsetting, SnapshotNow, numkeys, keys);
00209 while (HeapTupleIsValid(tup = heap_getnext(scan, ForwardScanDirection)))
00210 {
00211 simple_heap_delete(relsetting, &tup->t_self);
00212 }
00213 heap_endscan(scan);
00214
00215 heap_close(relsetting, RowExclusiveLock);
00216 }
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228 void
00229 ApplySetting(Oid databaseid, Oid roleid, Relation relsetting, GucSource source)
00230 {
00231 SysScanDesc scan;
00232 ScanKeyData keys[2];
00233 HeapTuple tup;
00234
00235 ScanKeyInit(&keys[0],
00236 Anum_pg_db_role_setting_setdatabase,
00237 BTEqualStrategyNumber,
00238 F_OIDEQ,
00239 ObjectIdGetDatum(databaseid));
00240 ScanKeyInit(&keys[1],
00241 Anum_pg_db_role_setting_setrole,
00242 BTEqualStrategyNumber,
00243 F_OIDEQ,
00244 ObjectIdGetDatum(roleid));
00245
00246 scan = systable_beginscan(relsetting, DbRoleSettingDatidRolidIndexId, true,
00247 SnapshotNow, 2, keys);
00248 while (HeapTupleIsValid(tup = systable_getnext(scan)))
00249 {
00250 bool isnull;
00251 Datum datum;
00252
00253 datum = heap_getattr(tup, Anum_pg_db_role_setting_setconfig,
00254 RelationGetDescr(relsetting), &isnull);
00255 if (!isnull)
00256 {
00257 ArrayType *a = DatumGetArrayTypeP(datum);
00258
00259
00260
00261
00262
00263
00264 ProcessGUCArray(a, PGC_SUSET, source, GUC_ACTION_SET);
00265 }
00266 }
00267
00268 systable_endscan(scan);
00269 }