| 62 | #define Atnum_pids 5 |
| 63 | |
| 64 | Datum |
| 65 | pgrowlocks(PG_FUNCTION_ARGS) |
| 66 | { |
| 67 | text *relname = PG_GETARG_TEXT_PP(0); |
| 68 | ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo; |
| 69 | bool randomAccess; |
| 70 | TupleDesc tupdesc; |
| 71 | Tuplestorestate *tupstore; |
| 72 | AttInMetadata *attinmeta; |
| 73 | Relation rel; |
| 74 | RangeVar *relrv; |
| 75 | TableScanDesc scan; |
| 76 | HeapScanDesc hscan; |
| 77 | HeapTuple tuple; |
| 78 | MemoryContext oldcontext; |
| 79 | AclResult aclresult; |
| 80 | char **values; |
| 81 | |
| 82 | /* check to see if caller supports us returning a tuplestore */ |
| 83 | if (rsinfo == NULL || !IsA(rsinfo, ReturnSetInfo)) |
| 84 | ereport(ERROR, |
| 85 | (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), |
| 86 | errmsg("set-valued function called in context that cannot accept a set"))); |
| 87 | if (!(rsinfo->allowedModes & SFRM_Materialize)) |
| 88 | ereport(ERROR, |
| 89 | (errcode(ERRCODE_SYNTAX_ERROR), |
| 90 | errmsg("materialize mode required, but it is not allowed in this context"))); |
| 91 | |
| 92 | /* The tupdesc and tuplestore must be created in ecxt_per_query_memory */ |
| 93 | oldcontext = MemoryContextSwitchTo(rsinfo->econtext->ecxt_per_query_memory); |
| 94 | |
| 95 | if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) |
| 96 | elog(ERROR, "return type must be a row type"); |
| 97 | |
| 98 | randomAccess = (rsinfo->allowedModes & SFRM_Materialize_Random) != 0; |
| 99 | tupstore = tuplestore_begin_heap(randomAccess, false, work_mem); |
| 100 | rsinfo->returnMode = SFRM_Materialize; |
| 101 | rsinfo->setResult = tupstore; |
| 102 | rsinfo->setDesc = tupdesc; |
| 103 | |
| 104 | MemoryContextSwitchTo(oldcontext); |
| 105 | |
| 106 | /* Access the table */ |
| 107 | relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname)); |
| 108 | rel = relation_openrv(relrv, AccessShareLock); |
| 109 | |
| 110 | if (rel->rd_rel->relam != HEAP_TABLE_AM_OID) |
| 111 | ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), |
| 112 | errmsg("only heap AM is supported"))); |
| 113 | |
| 114 | if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) |
| 115 | ereport(ERROR, |
| 116 | (errcode(ERRCODE_WRONG_OBJECT_TYPE), |
| 117 | errmsg("\"%s\" is a partitioned table", |
| 118 | RelationGetRelationName(rel)), |
| 119 | errdetail("Partitioned tables do not contain rows."))); |
| 120 | else if (rel->rd_rel->relkind != RELKIND_RELATION) |
| 121 | ereport(ERROR, |
nothing calls this directly
no test coverage detected