📄 regproc.c
字号:
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);}/* * regconfigin - converts "tsconfigname" to tsconfig 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_ts_config entry. * * This function is not needed in bootstrap mode, so we don't worry about * making it work then. */Datumregconfigin(PG_FUNCTION_ARGS){ char *cfg_name_or_oid = PG_GETARG_CSTRING(0); Oid result; List *names; /* '-' ? */ if (strcmp(cfg_name_or_oid, "-") == 0) PG_RETURN_OID(InvalidOid); /* Numeric OID? */ if (cfg_name_or_oid[0] >= '0' && cfg_name_or_oid[0] <= '9' && strspn(cfg_name_or_oid, "0123456789") == strlen(cfg_name_or_oid)) { result = DatumGetObjectId(DirectFunctionCall1(oidin, CStringGetDatum(cfg_name_or_oid))); PG_RETURN_OID(result); } /* * Normal case: parse the name into components and see if it matches any * pg_ts_config entries in the current search path. */ names = stringToQualifiedNameList(cfg_name_or_oid); result = TSConfigGetCfgid(names, false); PG_RETURN_OID(result);}/* * regconfigout - converts tsconfig OID to "tsconfigname" */Datumregconfigout(PG_FUNCTION_ARGS){ Oid cfgid = PG_GETARG_OID(0); char *result; HeapTuple cfgtup; if (cfgid == InvalidOid) { result = pstrdup("-"); PG_RETURN_CSTRING(result); } cfgtup = SearchSysCache(TSCONFIGOID, ObjectIdGetDatum(cfgid), 0, 0, 0); if (HeapTupleIsValid(cfgtup)) { Form_pg_ts_config cfgform = (Form_pg_ts_config) GETSTRUCT(cfgtup); char *cfgname = NameStr(cfgform->cfgname); char *nspname; /* * Would this config be found by regconfigin? If not, qualify it. */ if (TSConfigIsVisible(cfgid)) nspname = NULL; else nspname = get_namespace_name(cfgform->cfgnamespace); result = quote_qualified_identifier(nspname, cfgname); ReleaseSysCache(cfgtup); } else { /* If OID doesn't match any pg_ts_config row, return it numerically */ result = (char *) palloc(NAMEDATALEN); snprintf(result, NAMEDATALEN, "%u", cfgid); } PG_RETURN_CSTRING(result);}/* * regconfigrecv - converts external binary format to regconfig */Datumregconfigrecv(PG_FUNCTION_ARGS){ /* Exactly the same as oidrecv, so share code */ return oidrecv(fcinfo);}/* * regconfigsend - converts regconfig to binary format */Datumregconfigsend(PG_FUNCTION_ARGS){ /* Exactly the same as oidsend, so share code */ return oidsend(fcinfo);}/* * regdictionaryin - converts "tsdictionaryname" to tsdictionary 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_ts_dict entry. * * This function is not needed in bootstrap mode, so we don't worry about * making it work then. */Datumregdictionaryin(PG_FUNCTION_ARGS){ char *dict_name_or_oid = PG_GETARG_CSTRING(0); Oid result; List *names; /* '-' ? */ if (strcmp(dict_name_or_oid, "-") == 0) PG_RETURN_OID(InvalidOid); /* Numeric OID? */ if (dict_name_or_oid[0] >= '0' && dict_name_or_oid[0] <= '9' && strspn(dict_name_or_oid, "0123456789") == strlen(dict_name_or_oid)) { result = DatumGetObjectId(DirectFunctionCall1(oidin, CStringGetDatum(dict_name_or_oid))); PG_RETURN_OID(result); } /* * Normal case: parse the name into components and see if it matches any * pg_ts_dict entries in the current search path. */ names = stringToQualifiedNameList(dict_name_or_oid); result = TSDictionaryGetDictid(names, false); PG_RETURN_OID(result);}/* * regdictionaryout - converts tsdictionary OID to "tsdictionaryname" */Datumregdictionaryout(PG_FUNCTION_ARGS){ Oid dictid = PG_GETARG_OID(0); char *result; HeapTuple dicttup; if (dictid == InvalidOid) { result = pstrdup("-"); PG_RETURN_CSTRING(result); } dicttup = SearchSysCache(TSDICTOID, ObjectIdGetDatum(dictid), 0, 0, 0); if (HeapTupleIsValid(dicttup)) { Form_pg_ts_dict dictform = (Form_pg_ts_dict) GETSTRUCT(dicttup); char *dictname = NameStr(dictform->dictname); char *nspname; /* * Would this dictionary be found by regdictionaryin? If not, qualify * it. */ if (TSDictionaryIsVisible(dictid)) nspname = NULL; else nspname = get_namespace_name(dictform->dictnamespace); result = quote_qualified_identifier(nspname, dictname); ReleaseSysCache(dicttup); } else { /* If OID doesn't match any pg_ts_dict row, return it numerically */ result = (char *) palloc(NAMEDATALEN); snprintf(result, NAMEDATALEN, "%u", dictid); } PG_RETURN_CSTRING(result);}/* * regdictionaryrecv - converts external binary format to regdictionary */Datumregdictionaryrecv(PG_FUNCTION_ARGS){ /* Exactly the same as oidrecv, so share code */ return oidrecv(fcinfo);}/* * regdictionarysend - converts regdictionary to binary format */Datumregdictionarysend(PG_FUNCTION_ARGS){ /* Exactly the same as oidsend, so share code */ return oidsend(fcinfo);}/* * text_regclass: convert text to regclass * * This could be replaced by CoerceViaIO, except that we need to treat * text-to-regclass as an implicit cast to support legacy forms of nextval() * and related functions. */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){ 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, 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); /* 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 + -