* Find the compression implementation (in pg_compression) for a particular * compression type. * * Comparison is case insensitive. * * NOTE: This function performs a catalog lookup, which can cause cache * invalidation. If 'comptype' points to the relcache, i.e. * RelationData->rd_appendonly->compresstype, that reference is no longer * valid after the call! */
| 105 | * valid after the call! |
| 106 | */ |
| 107 | PGFunction * |
| 108 | GetCompressionImplementation(char *comptype) |
| 109 | { |
| 110 | HeapTuple tuple; |
| 111 | NameData compname; |
| 112 | PGFunction *funcs; |
| 113 | Form_pg_compression ctup; |
| 114 | FmgrInfo finfo; |
| 115 | Relation comprel; |
| 116 | ScanKeyData scankey; |
| 117 | SysScanDesc scan; |
| 118 | |
| 119 | /* |
| 120 | * Many callers pass RelationData->rd_appendonly->compresstype as |
| 121 | * the argument. That can become invalid, if table_open below causes |
| 122 | * a relcache invalidation. Call comptype_to_name() on the argument |
| 123 | * first, to make a copy of it before we call table_open(). |
| 124 | * |
| 125 | * This is hazardous to the callers, too, if they try to use the |
| 126 | * string after the call for something else, but there isn't much |
| 127 | * we can do about it here. |
| 128 | */ |
| 129 | compname = comptype_to_name(comptype); |
| 130 | |
| 131 | comprel = table_open(CompressionRelationId, AccessShareLock); |
| 132 | |
| 133 | comptype = NULL; /* table_open might have invalidated this */ |
| 134 | |
| 135 | /* SELECT * FROM pg_compression WHERE compname = :1 */ |
| 136 | ScanKeyInit(&scankey, |
| 137 | Anum_pg_compression_compname, |
| 138 | BTEqualStrategyNumber, F_NAMEEQ, |
| 139 | NameGetDatum(&compname)); |
| 140 | |
| 141 | scan = systable_beginscan(comprel, CompressionCompnameIndexId, true, |
| 142 | NULL, 1, &scankey); |
| 143 | tuple = systable_getnext(scan); |
| 144 | if (!HeapTupleIsValid(tuple)) |
| 145 | ereport(ERROR, |
| 146 | (errcode(ERRCODE_UNDEFINED_OBJECT), |
| 147 | errmsg("unknown compress type \"%s\"", |
| 148 | NameStr(compname)))); |
| 149 | |
| 150 | funcs = palloc0(sizeof(PGFunction) * NUM_COMPRESS_FUNCS); |
| 151 | |
| 152 | ctup = (Form_pg_compression)GETSTRUCT(tuple); |
| 153 | |
| 154 | Assert(OidIsValid(ctup->compconstructor)); |
| 155 | fmgr_info(ctup->compconstructor, &finfo); |
| 156 | funcs[COMPRESSION_CONSTRUCTOR] = finfo.fn_addr; |
| 157 | |
| 158 | Assert(OidIsValid(ctup->compdestructor)); |
| 159 | fmgr_info(ctup->compdestructor, &finfo); |
| 160 | funcs[COMPRESSION_DESTRUCTOR] = finfo.fn_addr; |
| 161 | |
| 162 | Assert(OidIsValid(ctup->compcompressor)); |
| 163 | fmgr_info(ctup->compcompressor, &finfo); |
| 164 | funcs[COMPRESSION_COMPRESS] = finfo.fn_addr; |
no test coverage detected