/* * transformArrayType() * Get the element type of an array type in preparation for subscripting */ Oid transformArrayType(Oid arrayType) { Oid elementType; int fetchCount; /* Get the type tuple for the array */ elementType = caql_getoid_plus( NULL, &fetchCount, NULL, cql("SELECT typelem FROM pg_type " " WHERE oid = :1 ", ObjectIdGetDatum(arrayType))); if (!fetchCount) elog(ERROR, "cache lookup failed for type %u", arrayType); /* needn't check typisdefined since this will fail anyway */ if (!OidIsValid(elementType)) ereport(ERROR, (errcode(ERRCODE_DATATYPE_MISMATCH), errmsg("cannot subscript type %s because it is not an array", format_type_be(arrayType)))); return elementType; }
/* * Same as LookupExtProtocolFunction but returns the actual * protocol Oid. */ Oid LookupExtProtocolOid(const char *prot_name, bool missing_ok) { int fetchCount; Oid protOid = InvalidOid; /* * Check the pg_extprotocol relation to be certain the protocol * is there. */ protOid = caql_getoid_plus( NULL, &fetchCount, NULL, cql("SELECT oid FROM pg_extprotocol " " WHERE ptcname = :1 ", CStringGetDatum(prot_name))); if (0 == fetchCount) { if(!missing_ok) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("protocol \"%s\" does not exist", prot_name))); } return protOid; }
/* * GetResQueueForRole -- determine what resource queue a role is going to use. * * Notes * This could be called for each of ResLockPortal and ResUnLockPortal, but we * can eliminate a relation open and lock if it is cached. */ Oid GetResQueueForRole(Oid roleid) { bool isnull; int fetchCount; Oid queueid = InvalidOid; queueid = caql_getoid_plus( NULL, &fetchCount, &isnull, cql("SELECT rolresqueue FROM pg_authid " " WHERE oid = :1 ", ObjectIdGetDatum(roleid))); /* MPP-6926: use default queue if none specified */ if (!OidIsValid(queueid) || !fetchCount || isnull) queueid = DEFAULTRESQUEUE_OID; return queueid; }
/* * regtypein - converts "typename" to type OID * * We also accept a numeric OID, for symmetry with the output routine. * * '-' signifies unknown (OID 0). In all other cases, the input must * match an existing pg_type entry. * * In bootstrap mode the name must just equal some existing name in pg_type. * In normal mode the type name can be specified using the full type syntax * recognized by the parser; for example, DOUBLE PRECISION and INTEGER[] will * work and be translated to the correct type names. (We ignore any typmod * info generated by the parser, however.) */ Datum regtypein(PG_FUNCTION_ARGS) { char *typ_name_or_oid = PG_GETARG_CSTRING(0); Oid result = InvalidOid; int32 typmod; /* '-' ? */ if (strcmp(typ_name_or_oid, "-") == 0) PG_RETURN_OID(InvalidOid); /* Numeric OID? */ if (typ_name_or_oid[0] >= '0' && typ_name_or_oid[0] <= '9' && strspn(typ_name_or_oid, "0123456789") == strlen(typ_name_or_oid)) { result = DatumGetObjectId(DirectFunctionCall1(oidin, CStringGetDatum(typ_name_or_oid))); PG_RETURN_OID(result); } /* Else it's a type name, possibly schema-qualified or decorated */ /* * In bootstrap mode we assume the given name is not schema-qualified, and * just search pg_type for a match. This is needed for initializing other * system catalogs (pg_namespace may not exist yet, and certainly there * are no schemas other than pg_catalog). */ if (IsBootstrapProcessingMode()) { int matches = 0; result = caql_getoid_plus( NULL, &matches, NULL, cql("SELECT oid FROM pg_type " " WHERE typname = :1 ", CStringGetDatum(typ_name_or_oid))); if (0 == matches) { ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("type \"%s\" does not exist", typ_name_or_oid))); } /* We assume there can be only one match */ PG_RETURN_OID(result); } /* * Normal case: invoke the full parser to deal with special cases such as * array syntax. */ parseTypeString(typ_name_or_oid, &result, &typmod); PG_RETURN_OID(result); }
/* * regclassin - converts "classname" to class OID * * We also accept a numeric OID, for symmetry with the output routine. * * '-' signifies unknown (OID 0). In all other cases, the input must * match an existing pg_class entry. */ Datum regclassin(PG_FUNCTION_ARGS) { char *class_name_or_oid = PG_GETARG_CSTRING(0); Oid result = InvalidOid; List *names; /* '-' ? */ if (strcmp(class_name_or_oid, "-") == 0) PG_RETURN_OID(InvalidOid); /* Numeric OID? */ if (class_name_or_oid[0] >= '0' && class_name_or_oid[0] <= '9' && strspn(class_name_or_oid, "0123456789") == strlen(class_name_or_oid)) { result = DatumGetObjectId(DirectFunctionCall1(oidin, CStringGetDatum(class_name_or_oid))); PG_RETURN_OID(result); } /* Else it's a name, possibly schema-qualified */ /* * In bootstrap mode we assume the given name is not schema-qualified, and * just search pg_class for a match. This is needed for initializing * other system catalogs (pg_namespace may not exist yet, and certainly * there are no schemas other than pg_catalog). */ if (IsBootstrapProcessingMode()) { int matches = 0; result = caql_getoid_plus( NULL, &matches, NULL, cql("SELECT oid FROM pg_class " " WHERE relname = :1 ", CStringGetDatum(class_name_or_oid))); if (0 == matches) { ereport(ERROR, (errcode(ERRCODE_UNDEFINED_TABLE), errmsg("relation \"%s\" does not exist", class_name_or_oid))); } /* We assume there can be only one match */ PG_RETURN_OID(result); } /* * Normal case: parse the name into components and see if it matches any * pg_class entries in the current search path. */ names = stringToQualifiedNameList(class_name_or_oid, "regclassin"); result = RangeVarGetRelid(makeRangeVarFromNameList(names), false, true /*allowHcatalog*/); PG_RETURN_OID(result); }
/* * regprocin - converts "proname" to proc OID * * We also accept a numeric OID, for symmetry with the output routine. * * '-' signifies unknown (OID 0). In all other cases, the input must * match an existing pg_proc entry. */ Datum regprocin(PG_FUNCTION_ARGS) { char *pro_name_or_oid = PG_GETARG_CSTRING(0); RegProcedure result = InvalidOid; List *names; FuncCandidateList clist; /* '-' ? */ if (strcmp(pro_name_or_oid, "-") == 0) PG_RETURN_OID(InvalidOid); /* Numeric OID? */ if (pro_name_or_oid[0] >= '0' && pro_name_or_oid[0] <= '9' && strspn(pro_name_or_oid, "0123456789") == strlen(pro_name_or_oid)) { result = DatumGetObjectId(DirectFunctionCall1(oidin, CStringGetDatum(pro_name_or_oid))); PG_RETURN_OID(result); } /* Else it's a name, possibly schema-qualified */ /* * In bootstrap mode we assume the given name is not schema-qualified, and * just search pg_proc for a unique match. This is needed for * initializing other system catalogs (pg_namespace may not exist yet, and * certainly there are no schemas other than pg_catalog). */ if (IsBootstrapProcessingMode()) { int matches = 0; result = (RegProcedure) caql_getoid_plus( NULL, &matches, NULL, cql("SELECT oid FROM pg_proc " " WHERE proname = :1 ", CStringGetDatum(pro_name_or_oid))); if (matches == 0) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_FUNCTION), errmsg("function \"%s\" does not exist", pro_name_or_oid))); else if (matches > 1) ereport(ERROR, (errcode(ERRCODE_AMBIGUOUS_FUNCTION), errmsg("more than one function named \"%s\"", pro_name_or_oid))); PG_RETURN_OID(result); } /* * Normal case: parse the name into components and see if it matches any * pg_proc entries in the current search path. */ names = stringToQualifiedNameList(pro_name_or_oid, "regprocin"); clist = FuncnameGetCandidates(names, -1); if (clist == NULL) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_FUNCTION), errmsg("function \"%s\" does not exist", pro_name_or_oid))); else if (clist->next != NULL) ereport(ERROR, (errcode(ERRCODE_AMBIGUOUS_FUNCTION), errmsg("more than one function named \"%s\"", pro_name_or_oid))); result = clist->oid; PG_RETURN_OID(result); }
/* * Finds an external protocol by passed in protocol name. * Errors if no such protocol exist, or if no function to * execute this protocol exists (for read or write separately). * * Returns the protocol function to use. */ Oid LookupExtProtocolFunction(const char *prot_name, ExtPtcFuncType prot_type, bool error) { bool isNull; Oid funcOid = InvalidOid; int fetchCount = 0; /* * Check the pg_extprotocol relation to be certain the protocol * is there. */ switch (prot_type) { case EXTPTC_FUNC_READER: funcOid = caql_getoid_plus( NULL, &fetchCount, &isNull, cql("SELECT ptcreadfn FROM pg_extprotocol " " WHERE ptcname = :1 ", CStringGetDatum(prot_name))); break; case EXTPTC_FUNC_WRITER: funcOid = caql_getoid_plus( NULL, &fetchCount, &isNull, cql("SELECT ptcwritefn FROM pg_extprotocol " " WHERE ptcname = :1 ", CStringGetDatum(prot_name))); break; case EXTPTC_FUNC_VALIDATOR: funcOid = caql_getoid_plus( NULL, &fetchCount, &isNull, cql("SELECT ptcvalidatorfn FROM pg_extprotocol " " WHERE ptcname = :1 ", CStringGetDatum(prot_name))); break; default: elog(ERROR, "internal error in pg_extprotocol:func_type_to_attnum"); break; } if (!fetchCount) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("protocol \"%s\" does not exist", prot_name))); /* cat attr is defined as NOT NULL */ Assert(!isNull); if (!OidIsValid(funcOid) && error) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("protocol '%s' has no %s function defined", prot_name, func_type_to_name(prot_type)))); return funcOid; }