|
3 | 3 | *back to source text
|
4 | 4 | *
|
5 | 5 | * IDENTIFICATION
|
6 |
| - * $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.173 2004/06/18 06:13:49 tgl Exp $ |
| 6 | + * $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.174 2004/06/25 17:20:24 tgl Exp $ |
7 | 7 | *
|
8 | 8 | * This software is copyrighted by Jan Wieck - Hamburg.
|
9 | 9 | *
|
|
42 | 42 |
|
43 | 43 | #include"access/genam.h"
|
44 | 44 | #include"catalog/catname.h"
|
| 45 | +#include"catalog/dependency.h" |
45 | 46 | #include"catalog/heap.h"
|
46 | 47 | #include"catalog/index.h"
|
47 | 48 | #include"catalog/indexing.h"
|
48 | 49 | #include"catalog/namespace.h"
|
49 | 50 | #include"catalog/pg_cast.h"
|
50 | 51 | #include"catalog/pg_constraint.h"
|
| 52 | +#include"catalog/pg_depend.h" |
51 | 53 | #include"catalog/pg_index.h"
|
52 | 54 | #include"catalog/pg_opclass.h"
|
53 | 55 | #include"catalog/pg_operator.h"
|
@@ -1232,6 +1234,116 @@ pg_get_userbyid(PG_FUNCTION_ARGS)
|
1232 | 1234 | PG_RETURN_NAME(result);
|
1233 | 1235 | }
|
1234 | 1236 |
|
| 1237 | + |
| 1238 | +/* |
| 1239 | + * pg_get_serial_sequence |
| 1240 | + *Get the name of the sequence used by a serial column, |
| 1241 | + *formatted suitably for passing to setval, nextval or currval. |
| 1242 | + */ |
| 1243 | +Datum |
| 1244 | +pg_get_serial_sequence(PG_FUNCTION_ARGS) |
| 1245 | +{ |
| 1246 | +text*tablename=PG_GETARG_TEXT_P(0); |
| 1247 | +text*columnname=PG_GETARG_TEXT_P(1); |
| 1248 | +RangeVar*tablerv; |
| 1249 | +OidtableOid; |
| 1250 | +char*column; |
| 1251 | +AttrNumberattnum; |
| 1252 | +OidsequenceId=InvalidOid; |
| 1253 | +RelationdepRel; |
| 1254 | +ScanKeyDatakey[3]; |
| 1255 | +SysScanDescscan; |
| 1256 | +HeapTupletup; |
| 1257 | + |
| 1258 | +/* Get the OID of the table */ |
| 1259 | +tablerv=makeRangeVarFromNameList(textToQualifiedNameList(tablename, |
| 1260 | +"pg_get_serial_sequence")); |
| 1261 | +tableOid=RangeVarGetRelid(tablerv, false); |
| 1262 | + |
| 1263 | +/* Get the number of the column */ |
| 1264 | +column=DatumGetCString(DirectFunctionCall1(textout, |
| 1265 | +PointerGetDatum(columnname))); |
| 1266 | + |
| 1267 | +attnum=get_attnum(tableOid,column); |
| 1268 | +if (attnum==InvalidAttrNumber) |
| 1269 | +ereport(ERROR, |
| 1270 | +(errcode(ERRCODE_UNDEFINED_COLUMN), |
| 1271 | +errmsg("column \"%s\" of relation \"%s\" does not exist", |
| 1272 | +column,tablerv->relname))); |
| 1273 | + |
| 1274 | +/* Search the dependency table for the dependent sequence */ |
| 1275 | +depRel=heap_openr(DependRelationName,AccessShareLock); |
| 1276 | + |
| 1277 | +ScanKeyInit(&key[0], |
| 1278 | +Anum_pg_depend_refclassid, |
| 1279 | +BTEqualStrategyNumber,F_OIDEQ, |
| 1280 | +ObjectIdGetDatum(RelOid_pg_class)); |
| 1281 | +ScanKeyInit(&key[1], |
| 1282 | +Anum_pg_depend_refobjid, |
| 1283 | +BTEqualStrategyNumber,F_OIDEQ, |
| 1284 | +ObjectIdGetDatum(tableOid)); |
| 1285 | +ScanKeyInit(&key[2], |
| 1286 | +Anum_pg_depend_refobjsubid, |
| 1287 | +BTEqualStrategyNumber,F_INT4EQ, |
| 1288 | +Int32GetDatum(attnum)); |
| 1289 | + |
| 1290 | +scan=systable_beginscan(depRel,DependReferenceIndex, true, |
| 1291 | +SnapshotNow,3,key); |
| 1292 | + |
| 1293 | +while (HeapTupleIsValid(tup=systable_getnext(scan))) |
| 1294 | +{ |
| 1295 | +Form_pg_dependdeprec= (Form_pg_depend)GETSTRUCT(tup); |
| 1296 | + |
| 1297 | +/* |
| 1298 | + * We assume any internal dependency of a relation on a column |
| 1299 | + * must be what we are looking for. |
| 1300 | + */ |
| 1301 | +if (deprec->classid==RelOid_pg_class&& |
| 1302 | +deprec->objsubid==0&& |
| 1303 | +deprec->deptype==DEPENDENCY_INTERNAL) |
| 1304 | +{ |
| 1305 | +sequenceId=deprec->objid; |
| 1306 | +break; |
| 1307 | +} |
| 1308 | +} |
| 1309 | + |
| 1310 | +systable_endscan(scan); |
| 1311 | +heap_close(depRel,AccessShareLock); |
| 1312 | + |
| 1313 | +if (OidIsValid(sequenceId)) |
| 1314 | +{ |
| 1315 | +HeapTupleclasstup; |
| 1316 | +Form_pg_classclasstuple; |
| 1317 | +char*nspname; |
| 1318 | +char*result; |
| 1319 | + |
| 1320 | +/* Get the sequence's pg_class entry */ |
| 1321 | +classtup=SearchSysCache(RELOID, |
| 1322 | +ObjectIdGetDatum(sequenceId), |
| 1323 | +0,0,0); |
| 1324 | +if (!HeapTupleIsValid(classtup)) |
| 1325 | +elog(ERROR,"cache lookup failed for relation %u",sequenceId); |
| 1326 | +classtuple= (Form_pg_class)GETSTRUCT(classtup); |
| 1327 | + |
| 1328 | +/* Get the namespace */ |
| 1329 | +nspname=get_namespace_name(classtuple->relnamespace); |
| 1330 | +if (!nspname) |
| 1331 | +elog(ERROR,"cache lookup failed for namespace %u", |
| 1332 | +classtuple->relnamespace); |
| 1333 | + |
| 1334 | +/* And construct the result string */ |
| 1335 | +result=quote_qualified_identifier(nspname, |
| 1336 | +NameStr(classtuple->relname)); |
| 1337 | + |
| 1338 | +ReleaseSysCache(classtup); |
| 1339 | + |
| 1340 | +PG_RETURN_TEXT_P(string_to_text(result)); |
| 1341 | +} |
| 1342 | + |
| 1343 | +PG_RETURN_NULL(); |
| 1344 | +} |
| 1345 | + |
| 1346 | + |
1235 | 1347 | /* ----------
|
1236 | 1348 | * deparse_expression- General utility for deparsing expressions
|
1237 | 1349 | *
|
|