lsyscache.c
来自「postgresql8.3.4源码,开源数据库」· C语言 代码 · 共 2,698 行 · 第 1/5 页
C
2,698 行
* or that it is in the database's default tablespace. */Oidget_rel_tablespace(Oid relid){ HeapTuple tp; tp = SearchSysCache(RELOID, ObjectIdGetDatum(relid), 0, 0, 0); if (HeapTupleIsValid(tp)) { Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp); Oid result; result = reltup->reltablespace; ReleaseSysCache(tp); return result; } else return InvalidOid;}/* ---------- TYPE CACHE ---------- *//* * get_typisdefined * * Given the type OID, determine whether the type is defined * (if not, it's only a shell). */boolget_typisdefined(Oid typid){ HeapTuple tp; tp = SearchSysCache(TYPEOID, ObjectIdGetDatum(typid), 0, 0, 0); if (HeapTupleIsValid(tp)) { Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp); bool result; result = typtup->typisdefined; ReleaseSysCache(tp); return result; } else return false;}/* * get_typlen * * Given the type OID, return the length of the type. */int16get_typlen(Oid typid){ HeapTuple tp; tp = SearchSysCache(TYPEOID, ObjectIdGetDatum(typid), 0, 0, 0); if (HeapTupleIsValid(tp)) { Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp); int16 result; result = typtup->typlen; ReleaseSysCache(tp); return result; } else return 0;}/* * get_typbyval * * Given the type OID, determine whether the type is returned by value or * not. Returns true if by value, false if by reference. */boolget_typbyval(Oid typid){ HeapTuple tp; tp = SearchSysCache(TYPEOID, ObjectIdGetDatum(typid), 0, 0, 0); if (HeapTupleIsValid(tp)) { Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp); bool result; result = typtup->typbyval; ReleaseSysCache(tp); return result; } else return false;}/* * get_typlenbyval * * A two-fer: given the type OID, return both typlen and typbyval. * * Since both pieces of info are needed to know how to copy a Datum, * many places need both. Might as well get them with one cache lookup * instead of two. Also, this routine raises an error instead of * returning a bogus value when given a bad type OID. */voidget_typlenbyval(Oid typid, int16 *typlen, bool *typbyval){ HeapTuple tp; Form_pg_type typtup; tp = SearchSysCache(TYPEOID, ObjectIdGetDatum(typid), 0, 0, 0); if (!HeapTupleIsValid(tp)) elog(ERROR, "cache lookup failed for type %u", typid); typtup = (Form_pg_type) GETSTRUCT(tp); *typlen = typtup->typlen; *typbyval = typtup->typbyval; ReleaseSysCache(tp);}/* * get_typlenbyvalalign * * A three-fer: given the type OID, return typlen, typbyval, typalign. */voidget_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval, char *typalign){ HeapTuple tp; Form_pg_type typtup; tp = SearchSysCache(TYPEOID, ObjectIdGetDatum(typid), 0, 0, 0); if (!HeapTupleIsValid(tp)) elog(ERROR, "cache lookup failed for type %u", typid); typtup = (Form_pg_type) GETSTRUCT(tp); *typlen = typtup->typlen; *typbyval = typtup->typbyval; *typalign = typtup->typalign; ReleaseSysCache(tp);}/* * getTypeIOParam * Given a pg_type row, select the type OID to pass to I/O functions * * Formerly, all I/O functions were passed pg_type.typelem as their second * parameter, but we now have a more complex rule about what to pass. * This knowledge is intended to be centralized here --- direct references * to typelem elsewhere in the code are wrong, if they are associated with * I/O calls and not with actual subscripting operations! (But see * bootstrap.c's boot_get_type_io_data() if you need to change this.) * * As of PostgreSQL 8.1, output functions receive only the value itself * and not any auxiliary parameters, so the name of this routine is now * a bit of a misnomer ... it should be getTypeInputParam. */OidgetTypeIOParam(HeapTuple typeTuple){ Form_pg_type typeStruct = (Form_pg_type) GETSTRUCT(typeTuple); /* * Array types get their typelem as parameter; everybody else gets their * own type OID as parameter. (As of 8.2, domains must get their own OID * even if their base type is an array.) */ if (typeStruct->typtype == TYPTYPE_BASE && OidIsValid(typeStruct->typelem)) return typeStruct->typelem; else return HeapTupleGetOid(typeTuple);}/* * get_type_io_data * * A six-fer: given the type OID, return typlen, typbyval, typalign, * typdelim, typioparam, and IO function OID. The IO function * returned is controlled by IOFuncSelector */voidget_type_io_data(Oid typid, IOFuncSelector which_func, int16 *typlen, bool *typbyval, char *typalign, char *typdelim, Oid *typioparam, Oid *func){ HeapTuple typeTuple; Form_pg_type typeStruct; /* * In bootstrap mode, pass it off to bootstrap.c. This hack allows us to * use array_in and array_out during bootstrap. */ if (IsBootstrapProcessingMode()) { Oid typinput; Oid typoutput; boot_get_type_io_data(typid, typlen, typbyval, typalign, typdelim, typioparam, &typinput, &typoutput); switch (which_func) { case IOFunc_input: *func = typinput; break; case IOFunc_output: *func = typoutput; break; default: elog(ERROR, "binary I/O not supported during bootstrap"); break; } return; } typeTuple = SearchSysCache(TYPEOID, ObjectIdGetDatum(typid), 0, 0, 0); if (!HeapTupleIsValid(typeTuple)) elog(ERROR, "cache lookup failed for type %u", typid); typeStruct = (Form_pg_type) GETSTRUCT(typeTuple); *typlen = typeStruct->typlen; *typbyval = typeStruct->typbyval; *typalign = typeStruct->typalign; *typdelim = typeStruct->typdelim; *typioparam = getTypeIOParam(typeTuple); switch (which_func) { case IOFunc_input: *func = typeStruct->typinput; break; case IOFunc_output: *func = typeStruct->typoutput; break; case IOFunc_receive: *func = typeStruct->typreceive; break; case IOFunc_send: *func = typeStruct->typsend; break; } ReleaseSysCache(typeTuple);}#ifdef NOT_USEDcharget_typalign(Oid typid){ HeapTuple tp; tp = SearchSysCache(TYPEOID, ObjectIdGetDatum(typid), 0, 0, 0); if (HeapTupleIsValid(tp)) { Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp); char result; result = typtup->typalign; ReleaseSysCache(tp); return result; } else return 'i';}#endifcharget_typstorage(Oid typid){ HeapTuple tp; tp = SearchSysCache(TYPEOID, ObjectIdGetDatum(typid), 0, 0, 0); if (HeapTupleIsValid(tp)) { Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp); char result; result = typtup->typstorage; ReleaseSysCache(tp); return result; } else return 'p';}/* * get_typdefault * Given a type OID, return the type's default value, if any. * * The result is a palloc'd expression node tree, or NULL if there * is no defined default for the datatype. * * NB: caller should be prepared to coerce result to correct datatype; * the returned expression tree might produce something of the wrong type. */Node *get_typdefault(Oid typid){ HeapTuple typeTuple; Form_pg_type type; Datum datum; bool isNull; Node *expr; typeTuple = SearchSysCache(TYPEOID, ObjectIdGetDatum(typid), 0, 0, 0); if (!HeapTupleIsValid(typeTuple)) elog(ERROR, "cache lookup failed for type %u", typid); type = (Form_pg_type) GETSTRUCT(typeTuple); /* * typdefault and typdefaultbin are potentially null, so don't try to * access 'em as struct fields. Must do it the hard way with * SysCacheGetAttr. */ datum = SysCacheGetAttr(TYPEOID, typeTuple, Anum_pg_type_typdefaultbin, &isNull); if (!isNull) { /* We have an expression default */ expr = stringToNode(DatumGetCString(DirectFunctionCall1(textout, datum))); } else { /* Perhaps we have a plain literal default */ datum = SysCacheGetAttr(TYPEOID, typeTuple, Anum_pg_type_typdefault, &isNull); if (!isNull) { char *strDefaultVal; /* Convert text datum to C string */ strDefaultVal = DatumGetCString(DirectFunctionCall1(textout, datum)); /* Convert C string to a value of the given type */ datum = OidInputFunctionCall(type->typinput, strDefaultVal, getTypeIOParam(typeTuple), -1); /* Build a Const node containing the value */ expr = (Node *) makeConst(typid, -1, type->typlen, datum, false, type->typbyval); pfree(strDefaultVal); } else { /* No default */ expr = NULL; } } ReleaseSysCache(typeTuple); return expr;}/* * getBaseType * If the given type is a domain, return its base type; * otherwise return the type's own OID. */OidgetBaseType(Oid typid){ int32 typmod = -1; return getBaseTypeAndTypmod(typid, &typmod);}/* * getBaseTypeAndTypmod * If the given type is a domain, return its base type and typmod; * otherwise return the type's own OID, and leave *typmod unchanged. * * Note that the "applied typmod" should be -1 for every domain level * above the bottommost; therefore, if the passed-in typid is indeed * a domain, *typmod should be -1. */OidgetBaseTypeAndTypmod(Oid typid, int32 *typmod){ /* * We loop to find the bottom base type in a stack of domains. */ for (;;) { HeapTuple tup; Form_pg_type typTup; tup = SearchSysCache(TYPEOID, ObjectIdGetDatum(typid), 0, 0, 0); if (!HeapTupleIsValid(tup)) elog(ERROR, "cache lookup failed for type %u", typid); typTup = (Form_pg_type) GETSTRUCT(tup); if (typTup->typtype != TYPTYPE_DOMAIN) { /* Not a domain, so done */ ReleaseSysCache(tup); break; } Assert(*typmod == -1); typid = typTup->typbasetype; *typmod = typTup->typtypmod; ReleaseSysCache(tup); } return typid;}/* * get_typavgwidth * * Given a type OID and a typmod value (pass -1 if typmod is unknown), * estimate the average width of values of the type. This is used by * the planner, which doesn't require absolutely correct results; * it's OK (and expected) to guess if we don't know for sure. */int32get_typavgwidth(Oid typid, int32 typmod){ int typlen = get_typlen(typid); int32 maxwidth; /* * Easy if it's a fixed-width type */ if (typlen > 0) return typlen; /* * type_maximum_size knows the encoding of typmod for some datatypes; * don't duplicate that knowledge here. */ maxwidth = type_maximum_size(typid, typmod); if (maxwidth > 0) { /* * For BPCHAR, the max width is also the only width. Otherwise we * need to guess about the typical data width given the max. A sliding * scale for percentage of max width seems reasonable. */ if (typid == BPCHAROID) return maxwidth; if (maxwidth <= 32) return maxwidth; /* assume full width */ if (maxwidth < 1000) return 32 + (maxwidth - 32) / 2; /* assume 50% */ /* * Beyond 1000, assume we're looking at something like * "varchar(10000)" where the limit isn't actually reached often, and * use a fixed estimate. */ return 32 + (1000 - 32) / 2; } /* * Ooops, we have no idea ... wild guess time. */ return 32;}/* * get_typtype * * Given the type OID, find if it is a basic type, a complex type, etc. * It returns the null char if the cache lookup fails... */charget_typtype(Oid typid){ HeapTuple tp; tp = SearchSysCache(TYPEOID, ObjectIdGetDatum(typid), 0, 0, 0); if (HeapTupleIsValid(tp)) { Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp); char result; result = typtup->typtype; ReleaseSysCache(tp); return result; } else return '\0';}/* * type_is_rowtype * * Convenience function to determine whether a type OID represents * a "rowtype" type --- either RECORD or a named composite type. */booltype_is_rowtype(Oid typid){
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?