/* * DROP CONVERSION */ void DropConversionCommand(List *name, DropBehavior behavior, bool missing_ok) { Oid conversionOid; conversionOid = FindConversionByName(name); if (!OidIsValid(conversionOid)) { if (!missing_ok) { ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("conversion \"%s\" does not exist", NameListToString(name)))); } else { if (Gp_role != GP_ROLE_EXECUTE) ereport(NOTICE, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("conversion \"%s\" does not exist, skipping", NameListToString(name)))); } return; } ConversionDrop(conversionOid, behavior); }
/* * Rename conversion */ void RenameConversion(List *name, const char *newname) { Oid conversionOid; Oid namespaceOid; HeapTuple tup; Relation rel; AclResult aclresult; rel = heap_openr(ConversionRelationName, RowExclusiveLock); conversionOid = FindConversionByName(name); if (!OidIsValid(conversionOid)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("conversion \"%s\" does not exist", NameListToString(name)))); tup = SearchSysCacheCopy(CONOID, ObjectIdGetDatum(conversionOid), 0, 0, 0); if (!HeapTupleIsValid(tup)) /* should not happen */ elog(ERROR, "cache lookup failed for conversion %u", conversionOid); namespaceOid = ((Form_pg_conversion) GETSTRUCT(tup))->connamespace; /* make sure the new name doesn't exist */ if (SearchSysCacheExists(CONNAMENSP, CStringGetDatum(newname), ObjectIdGetDatum(namespaceOid), 0, 0)) ereport(ERROR, (errcode(ERRCODE_DUPLICATE_OBJECT), errmsg("conversion \"%s\" already exists in schema \"%s\"", newname, get_namespace_name(namespaceOid)))); /* must be owner */ if (!superuser() && ((Form_pg_conversion) GETSTRUCT(tup))->conowner != GetUserId()) aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CONVERSION, NameListToString(name)); /* must have CREATE privilege on namespace */ aclresult = pg_namespace_aclcheck(namespaceOid, GetUserId(), ACL_CREATE); if (aclresult != ACLCHECK_OK) aclcheck_error(aclresult, ACL_KIND_NAMESPACE, get_namespace_name(namespaceOid)); /* rename */ namestrcpy(&(((Form_pg_conversion) GETSTRUCT(tup))->conname), newname); simple_heap_update(rel, &tup->t_self, tup); CatalogUpdateIndexes(rel, tup); heap_close(rel, NoLock); heap_freetuple(tup); }
/* * Change conversion owner */ void AlterConversionOwner(List *name, AclId newOwnerSysId) { Oid conversionOid; HeapTuple tup; Relation rel; Form_pg_conversion convForm; rel = heap_openr(ConversionRelationName, RowExclusiveLock); conversionOid = FindConversionByName(name); if (!OidIsValid(conversionOid)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("conversion \"%s\" does not exist", NameListToString(name)))); tup = SearchSysCacheCopy(CONOID, ObjectIdGetDatum(conversionOid), 0, 0, 0); if (!HeapTupleIsValid(tup)) /* should not happen */ elog(ERROR, "cache lookup failed for conversion %u", conversionOid); convForm = (Form_pg_conversion) GETSTRUCT(tup); /* * If the new owner is the same as the existing owner, consider the * command to have succeeded. This is for dump restoration purposes. */ if (convForm->conowner != newOwnerSysId) { /* Otherwise, must be superuser to change object ownership */ if (!superuser()) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("must be superuser to change owner"))); /* * Modify the owner --- okay to scribble on tup because it's a * copy */ convForm->conowner = newOwnerSysId; simple_heap_update(rel, &tup->t_self, tup); CatalogUpdateIndexes(rel, tup); } heap_close(rel, NoLock); heap_freetuple(tup); }
/* * DROP CONVERSION */ void DropConversionCommand(List *name, DropBehavior behavior) { Oid conversionOid; conversionOid = FindConversionByName(name); if (!OidIsValid(conversionOid)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("conversion \"%s\" does not exist", NameListToString(name)))); ConversionDrop(conversionOid, behavior); }
/* * Change conversion owner, by name */ void AlterConversionOwner(List *name, Oid newOwnerId) { Oid conversionOid; Relation rel; rel = heap_open(ConversionRelationId, RowExclusiveLock); conversionOid = FindConversionByName(name); if (!OidIsValid(conversionOid)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("conversion \"%s\" does not exist", NameListToString(name)))); AlterConversionOwner_internal(rel, conversionOid, newOwnerId); heap_close(rel, NoLock); }
/* * Rename conversion */ void RenameConversion(List *name, const char *newname) { Oid conversionOid; Oid namespaceOid; HeapTuple tup; Relation rel; AclResult aclresult; cqContext cqc2; cqContext cqc; cqContext *pcqCtx; rel = heap_open(ConversionRelationId, RowExclusiveLock); conversionOid = FindConversionByName(name); if (!OidIsValid(conversionOid)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("conversion \"%s\" does not exist", NameListToString(name)))); pcqCtx = caql_addrel(cqclr(&cqc), rel); tup = caql_getfirst( pcqCtx, cql("SELECT * FROM pg_conversion " " WHERE oid = :1 " " FOR UPDATE ", ObjectIdGetDatum(conversionOid))); if (!HeapTupleIsValid(tup)) /* should not happen */ elog(ERROR, "cache lookup failed for conversion %u", conversionOid); namespaceOid = ((Form_pg_conversion) GETSTRUCT(tup))->connamespace; /* make sure the new name doesn't exist */ if (caql_getcount( caql_addrel(cqclr(&cqc2), rel), cql("SELECT COUNT(*) FROM pg_conversion " " WHERE conname = :1 " " AND connamespace = :2 ", CStringGetDatum((char *) newname), ObjectIdGetDatum(namespaceOid)))) { ereport(ERROR, (errcode(ERRCODE_DUPLICATE_OBJECT), errmsg("conversion \"%s\" already exists in schema \"%s\"", newname, get_namespace_name(namespaceOid)))); } /* must be owner */ if (!pg_conversion_ownercheck(conversionOid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CONVERSION, NameListToString(name)); /* must have CREATE privilege on namespace */ aclresult = pg_namespace_aclcheck(namespaceOid, GetUserId(), ACL_CREATE); if (aclresult != ACLCHECK_OK) aclcheck_error(aclresult, ACL_KIND_NAMESPACE, get_namespace_name(namespaceOid)); /* rename */ namestrcpy(&(((Form_pg_conversion) GETSTRUCT(tup))->conname), newname); caql_update_current(pcqCtx, tup); /* implicit update of index as well */ heap_close(rel, NoLock); heap_freetuple(tup); }
/* * Execute SQL99's CONVERT function. * * CONVERT <left paren> <character value expression> * USING <form-of-use conversion name> <right paren> * * TEXT convert_using(TEXT string, TEXT conversion_name) */ Datum pg_convert_using(PG_FUNCTION_ARGS) { text *string = PG_GETARG_TEXT_P(0); text *conv_name = PG_GETARG_TEXT_P(1); text *retval; List *parsed_name; Oid convoid; HeapTuple tuple; Form_pg_conversion body; char *str; char *result; int len; /* Convert input string to null-terminated form */ len = VARSIZE(string) - VARHDRSZ; str = palloc(len + 1); memcpy(str, VARDATA(string), len); *(str + len) = '\0'; /* Look up the conversion name */ parsed_name = textToQualifiedNameList(conv_name); convoid = FindConversionByName(parsed_name); if (!OidIsValid(convoid)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("conversion \"%s\" does not exist", NameListToString(parsed_name)))); tuple = SearchSysCache(CONOID, ObjectIdGetDatum(convoid), 0, 0, 0); if (!HeapTupleIsValid(tuple)) elog(ERROR, "cache lookup failed for conversion %u", convoid); body = (Form_pg_conversion) GETSTRUCT(tuple); /* Temporary result area should be more than big enough */ result = palloc(len * 4 + 1); OidFunctionCall5(body->conproc, Int32GetDatum(body->conforencoding), Int32GetDatum(body->contoencoding), CStringGetDatum(str), CStringGetDatum(result), Int32GetDatum(len)); ReleaseSysCache(tuple); /* * build text result structure. we cannot use textin() here, since textin * assumes that input string encoding is same as database encoding. */ len = strlen(result) + VARHDRSZ; retval = palloc(len); VARATT_SIZEP(retval) = len; memcpy(VARDATA(retval), result, len - VARHDRSZ); pfree(result); pfree(str); PG_RETURN_TEXT_P(retval); }