📄 regproc.c
字号:
result = pstrdup("-"); PG_RETURN_CSTRING(result); } classtup = SearchSysCache(RELOID, ObjectIdGetDatum(classid), 0, 0, 0); if (HeapTupleIsValid(classtup)) { Form_pg_class classform = (Form_pg_class) GETSTRUCT(classtup); char *classname = NameStr(classform->relname); /* * In bootstrap mode, skip the fancy namespace stuff and just return * the class name. (This path is only needed for debugging output * anyway.) */ if (IsBootstrapProcessingMode()) result = pstrdup(classname); else { char *nspname; /* * Would this class be found by regclassin? If not, qualify it. */ if (RelationIsVisible(classid)) nspname = NULL; else nspname = get_namespace_name(classform->relnamespace); result = quote_qualified_identifier(nspname, classname); } ReleaseSysCache(classtup); } else { /* If OID doesn't match any pg_class entry, return it numerically */ result = (char *) palloc(NAMEDATALEN); snprintf(result, NAMEDATALEN, "%u", classid); } PG_RETURN_CSTRING(result);}/* * regclassrecv - converts external binary format to regclass */Datumregclassrecv(PG_FUNCTION_ARGS){ /* Exactly the same as oidrecv, so share code */ return oidrecv(fcinfo);}/* * regclasssend - converts regclass to binary format */Datumregclasssend(PG_FUNCTION_ARGS){ /* Exactly the same as oidsend, so share code */ return oidsend(fcinfo);}/* * 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.) */Datumregtypein(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()) { Relation hdesc; ScanKeyData skey[1]; SysScanDesc sysscan; HeapTuple tuple; ScanKeyInit(&skey[0], Anum_pg_type_typname, BTEqualStrategyNumber, F_NAMEEQ, CStringGetDatum(typ_name_or_oid)); hdesc = heap_open(TypeRelationId, AccessShareLock); sysscan = systable_beginscan(hdesc, TypeNameNspIndexId, true, SnapshotNow, 1, skey); if (HeapTupleIsValid(tuple = systable_getnext(sysscan))) result = HeapTupleGetOid(tuple); else ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("type \"%s\" does not exist", typ_name_or_oid))); /* We assume there can be only one match */ systable_endscan(sysscan); heap_close(hdesc, AccessShareLock); 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);}/* * regtypeout - converts type OID to "typ_name" */Datumregtypeout(PG_FUNCTION_ARGS){ Oid typid = PG_GETARG_OID(0); char *result; HeapTuple typetup; if (typid == InvalidOid) { result = pstrdup("-"); PG_RETURN_CSTRING(result); } typetup = SearchSysCache(TYPEOID, ObjectIdGetDatum(typid), 0, 0, 0); if (HeapTupleIsValid(typetup)) { Form_pg_type typeform = (Form_pg_type) GETSTRUCT(typetup); /* * In bootstrap mode, skip the fancy namespace stuff and just return * the type name. (This path is only needed for debugging output * anyway.) */ if (IsBootstrapProcessingMode()) { char *typname = NameStr(typeform->typname); result = pstrdup(typname); } else result = format_type_be(typid); ReleaseSysCache(typetup); } else { /* If OID doesn't match any pg_type entry, return it numerically */ result = (char *) palloc(NAMEDATALEN); snprintf(result, NAMEDATALEN, "%u", typid); } PG_RETURN_CSTRING(result);}/* * regtyperecv - converts external binary format to regtype */Datumregtyperecv(PG_FUNCTION_ARGS){ /* Exactly the same as oidrecv, so share code */ return oidrecv(fcinfo);}/* * regtypesend - converts regtype to binary format */Datumregtypesend(PG_FUNCTION_ARGS){ /* Exactly the same as oidsend, so share code */ return oidsend(fcinfo);}/* * text_regclass: convert text to regclass */Datumtext_regclass(PG_FUNCTION_ARGS){ text *relname = PG_GETARG_TEXT_P(0); Oid result; RangeVar *rv; rv = makeRangeVarFromNameList(textToQualifiedNameList(relname)); result = RangeVarGetRelid(rv, false); PG_RETURN_OID(result);}/* * Given a C string, parse it into a qualified-name list. */List *stringToQualifiedNameList(const char *string, const char *caller){ char *rawname; List *result = NIL; List *namelist; ListCell *l; /* We need a modifiable copy of the input string. */ rawname = pstrdup(string); if (!SplitIdentifierString(rawname, '.', &namelist)) ereport(ERROR, (errcode(ERRCODE_INVALID_NAME), errmsg("invalid name syntax"))); if (namelist == NIL) ereport(ERROR, (errcode(ERRCODE_INVALID_NAME), errmsg("invalid name syntax"))); foreach(l, namelist) { char *curname = (char *) lfirst(l); result = lappend(result, makeString(pstrdup(curname))); } pfree(rawname); list_free(namelist); return result;}/***************************************************************************** * SUPPORT ROUTINES * *****************************************************************************//* * Given a C string, parse it into a qualified function or operator name * followed by a parenthesized list of type names. Reduce the * type names to an array of OIDs (returned into *nargs and *argtypes; * the argtypes array should be of size FUNC_MAX_ARGS). The function or * operator name is returned to *names as a List of Strings. * * If allowNone is TRUE, accept "NONE" and return it as InvalidOid (this is * for unary operators). */static voidparseNameAndArgTypes(const char *string, const char *caller, bool allowNone, List **names, int *nargs, Oid *argtypes){ char *rawname; char *ptr; char *ptr2; char *typename; bool in_quote; bool had_comma; int paren_count; Oid typeid; int32 typmod; /* We need a modifiable copy of the input string. */ rawname = pstrdup(string); /* Scan to find the expected left paren; mustn't be quoted */ in_quote = false; for (ptr = rawname; *ptr; ptr++) { if (*ptr == '"') in_quote = !in_quote; else if (*ptr == '(' && !in_quote) break; } if (*ptr == '\0') ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("expected a left parenthesis"))); /* Separate the name and parse it into a list */ *ptr++ = '\0'; *names = stringToQualifiedNameList(rawname, caller); /* Check for the trailing right parenthesis and remove it */ ptr2 = ptr + strlen(ptr); while (--ptr2 > ptr) { if (!isspace((unsigned char) *ptr2)) break; } if (*ptr2 != ')') ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("expected a right parenthesis"))); *ptr2 = '\0'; /* Separate the remaining string into comma-separated type names */ *nargs = 0; had_comma = false; for (;;) { /* allow leading whitespace */ while (isspace((unsigned char) *ptr)) ptr++; if (*ptr == '\0') { /* End of string. Okay unless we had a comma before. */ if (had_comma) ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("expected a type name"))); break; } typename = ptr; /* Find end of type name --- end of string or comma */ /* ... but not a quoted or parenthesized comma */ in_quote = false; paren_count = 0; for (; *ptr; ptr++) { if (*ptr == '"') in_quote = !in_quote; else if (*ptr == ',' && !in_quote && paren_count == 0) break; else if (!in_quote) { switch (*ptr) { case '(': case '[': paren_count++; break; case ')': case ']': paren_count--; break; } } } if (in_quote || paren_count != 0) ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("improper type name"))); ptr2 = ptr; if (*ptr == ',') { had_comma = true; *ptr++ = '\0'; } else { had_comma = false; Assert(*ptr == '\0'); } /* Lop off trailing whitespace */ while (--ptr2 >= typename) { if (!isspace((unsigned char) *ptr2)) break; *ptr2 = '\0'; } if (allowNone && pg_strcasecmp(typename, "none") == 0) { /* Special case for NONE */ typeid = InvalidOid; typmod = -1; } else { /* Use full parser to resolve the type name */ parseTypeString(typename, &typeid, &typmod); } if (*nargs >= FUNC_MAX_ARGS) ereport(ERROR, (errcode(ERRCODE_TOO_MANY_ARGUMENTS), errmsg("too many arguments"))); argtypes[*nargs] = typeid; (*nargs)++; } pfree(rawname);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -