/* * ConversionCreate * * Add a new tuple to pg_conversion. */ Oid ConversionCreate(const char *conname, Oid connamespace, Oid conowner, int32 conforencoding, int32 contoencoding, Oid conproc, bool def) { int i; Relation rel; TupleDesc tupDesc; HeapTuple tup; bool nulls[Natts_pg_conversion]; Datum values[Natts_pg_conversion]; NameData cname; Oid oid; ObjectAddress myself, referenced; /* sanity checks */ if (!conname) elog(ERROR, "no conversion name supplied"); /* make sure there is no existing conversion of same name */ if (SearchSysCacheExists2(CONNAMENSP, PointerGetDatum(conname), ObjectIdGetDatum(connamespace))) ereport(ERROR, (errcode(ERRCODE_DUPLICATE_OBJECT), errmsg("conversion \"%s\" already exists", conname))); if (def) { /* * make sure there is no existing default <for encoding><to encoding> * pair in this name space */ if (FindDefaultConversion(connamespace, conforencoding, contoencoding)) ereport(ERROR, (errcode(ERRCODE_DUPLICATE_OBJECT), errmsg("default conversion for %s to %s already exists", pg_encoding_to_char(conforencoding), pg_encoding_to_char(contoencoding)))); } /* open pg_conversion */ rel = heap_open(ConversionRelationId, RowExclusiveLock); tupDesc = rel->rd_att; /* initialize nulls and values */ for (i = 0; i < Natts_pg_conversion; i++) { nulls[i] = false; values[i] = (Datum) NULL; } /* form a tuple */ namestrcpy(&cname, conname); values[Anum_pg_conversion_conname - 1] = NameGetDatum(&cname); values[Anum_pg_conversion_connamespace - 1] = ObjectIdGetDatum(connamespace); values[Anum_pg_conversion_conowner - 1] = ObjectIdGetDatum(conowner); values[Anum_pg_conversion_conforencoding - 1] = Int32GetDatum(conforencoding); values[Anum_pg_conversion_contoencoding - 1] = Int32GetDatum(contoencoding); values[Anum_pg_conversion_conproc - 1] = ObjectIdGetDatum(conproc); values[Anum_pg_conversion_condefault - 1] = BoolGetDatum(def); tup = heap_form_tuple(tupDesc, values, nulls); /* insert a new tuple */ oid = simple_heap_insert(rel, tup); Assert(OidIsValid(oid)); /* update the index if any */ CatalogUpdateIndexes(rel, tup); myself.classId = ConversionRelationId; myself.objectId = HeapTupleGetOid(tup); myself.objectSubId = 0; /* create dependency on conversion procedure */ referenced.classId = ProcedureRelationId; referenced.objectId = conproc; referenced.objectSubId = 0; recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); /* create dependency on namespace */ referenced.classId = NamespaceRelationId; referenced.objectId = connamespace; referenced.objectSubId = 0; recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); /* create dependency on owner */ recordDependencyOnOwner(ConversionRelationId, HeapTupleGetOid(tup), conowner); /* dependency on extension */ recordDependencyOnCurrentExtension(&myself, false); /* Post creation hook for new conversion */ InvokeObjectPostCreateHook(ConversionRelationId, HeapTupleGetOid(tup), 0); heap_freetuple(tup); heap_close(rel, RowExclusiveLock); return oid; }
/* * ConversionCreate * * Add a new tuple to pg_conversion. */ Oid ConversionCreate(const char *conname, Oid connamespace, Oid conowner, int32 conforencoding, int32 contoencoding, Oid conproc, bool def, Oid newOid) { int i; Relation rel; HeapTuple tup; bool nulls[Natts_pg_conversion]; Datum values[Natts_pg_conversion]; NameData cname; Oid oid; ObjectAddress myself, referenced; cqContext cqc; cqContext *pcqCtx; /* sanity checks */ if (!conname) elog(ERROR, "no conversion name supplied"); /* open pg_conversion */ rel = heap_open(ConversionRelationId, RowExclusiveLock); /* make sure there is no existing conversion of same name */ if (caql_getcount( caql_addrel(cqclr(&cqc), rel), cql("SELECT COUNT(*) FROM pg_conversion " " WHERE conname = :1 " " AND connamespace = :2 ", CStringGetDatum((char *) conname), ObjectIdGetDatum(connamespace)))) { ereport(ERROR, (errcode(ERRCODE_DUPLICATE_OBJECT), errmsg("conversion \"%s\" already exists", conname))); } if (def) { /* * make sure there is no existing default <for encoding><to encoding> * pair in this name space */ if (FindDefaultConversion(connamespace, conforencoding, contoencoding)) ereport(ERROR, (errcode(ERRCODE_DUPLICATE_OBJECT), errmsg("default conversion for %s to %s already exists", pg_encoding_to_char(conforencoding), pg_encoding_to_char(contoencoding)))); } pcqCtx = caql_beginscan( caql_addrel(cqclr(&cqc), rel), cql("INSERT INTO pg_conversion", NULL)); /* initialize nulls and values */ for (i = 0; i < Natts_pg_conversion; i++) { nulls[i] = false; values[i] = (Datum) 0; } /* form a tuple */ namestrcpy(&cname, conname); values[Anum_pg_conversion_conname - 1] = NameGetDatum(&cname); values[Anum_pg_conversion_connamespace - 1] = ObjectIdGetDatum(connamespace); values[Anum_pg_conversion_conowner - 1] = ObjectIdGetDatum(conowner); values[Anum_pg_conversion_conforencoding - 1] = Int32GetDatum(conforencoding); values[Anum_pg_conversion_contoencoding - 1] = Int32GetDatum(contoencoding); values[Anum_pg_conversion_conproc - 1] = ObjectIdGetDatum(conproc); values[Anum_pg_conversion_condefault - 1] = BoolGetDatum(def); tup = caql_form_tuple(pcqCtx, values, nulls); if (newOid != 0) HeapTupleSetOid(tup, newOid); /* insert a new tuple */ oid = caql_insert(pcqCtx, tup); /* implicit update of index as well */ Assert(OidIsValid(oid)); myself.classId = ConversionRelationId; myself.objectId = HeapTupleGetOid(tup); myself.objectSubId = 0; /* create dependency on conversion procedure */ referenced.classId = ProcedureRelationId; referenced.objectId = conproc; referenced.objectSubId = 0; recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); /* create dependency on namespace */ referenced.classId = NamespaceRelationId; referenced.objectId = connamespace; referenced.objectSubId = 0; recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); /* create dependency on owner */ recordDependencyOnOwner(ConversionRelationId, HeapTupleGetOid(tup), conowner); heap_freetuple(tup); caql_endscan(pcqCtx); heap_close(rel, RowExclusiveLock); return oid; }