/* * sepgsql_set_client_label * * This routine tries to switch the current security label of the client, and * checks related permissions. The supplied new label shall be added to the * client_label_pending list, then saved at transaction-commit time to ensure * transaction-awareness. */ static void sepgsql_set_client_label(const char *new_label) { const char *tcontext; MemoryContext oldcxt; pending_label *plabel; /* Reset to the initial client label, if NULL */ if (!new_label) tcontext = client_label_peer; else { if (security_check_context_raw((security_context_t) new_label) < 0) ereport(ERROR, (errcode(ERRCODE_INVALID_NAME), errmsg("SELinux: invalid security label: \"%s\"", new_label))); tcontext = new_label; } /* Check process:{setcurrent} permission. */ sepgsql_avc_check_perms_label(sepgsql_get_client_label(), SEPG_CLASS_PROCESS, SEPG_PROCESS__SETCURRENT, NULL, true); /* Check process:{dyntransition} permission. */ sepgsql_avc_check_perms_label(tcontext, SEPG_CLASS_PROCESS, SEPG_PROCESS__DYNTRANSITION, NULL, true); /* * Append the supplied new_label on the pending list until the current * transaction is committed. */ oldcxt = MemoryContextSwitchTo(CurTransactionContext); plabel = palloc0(sizeof(pending_label)); plabel->subid = GetCurrentSubTransactionId(); if (new_label) plabel->label = pstrdup(new_label); client_label_pending = lappend(client_label_pending, plabel); MemoryContextSwitchTo(oldcxt); }
/* * Get all relations for subscription that are not in a ready state. * * Returned list is palloc'ed in current memory context. */ List * GetSubscriptionNotReadyRelations(Oid subid) { List *res = NIL; Relation rel; HeapTuple tup; int nkeys = 0; ScanKeyData skey[2]; SysScanDesc scan; rel = table_open(SubscriptionRelRelationId, AccessShareLock); ScanKeyInit(&skey[nkeys++], Anum_pg_subscription_rel_srsubid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(subid)); ScanKeyInit(&skey[nkeys++], Anum_pg_subscription_rel_srsubstate, BTEqualStrategyNumber, F_CHARNE, CharGetDatum(SUBREL_STATE_READY)); scan = systable_beginscan(rel, InvalidOid, false, NULL, nkeys, skey); while (HeapTupleIsValid(tup = systable_getnext(scan))) { Form_pg_subscription_rel subrel; SubscriptionRelState *relstate; subrel = (Form_pg_subscription_rel) GETSTRUCT(tup); relstate = (SubscriptionRelState *) palloc(sizeof(SubscriptionRelState)); relstate->relid = subrel->srrelid; relstate->state = subrel->srsubstate; relstate->lsn = subrel->srsublsn; res = lappend(res, relstate); } /* Cleanup */ systable_endscan(scan); table_close(rel, AccessShareLock); return res; }
/* * Append to list1 each member of list2 that isn't already in list1. * * Whether an element is already a member of the list is determined * via equal(). * * This is almost the same functionality as list_union(), but list1 is * modified in-place rather than being copied. Note also that list2's cells * are not inserted in list1, so the analogy to list_concat() isn't perfect. */ List * list_concat_unique(List *list1, List *list2) { ListCell *cell; Assert(IsPointerList(list1)); Assert(IsPointerList(list2)); foreach(cell, list2) { if (!list_member(list1, lfirst(cell))) list1 = lappend(list1, lfirst(cell)); } check_list_invariants(list1); return list1; }
/* * LoadShardList reads list of shards for given relationId from pg_dist_shard, * and returns the list of found shardIds. */ List * LoadShardList(Oid relationId) { DistTableCacheEntry *cacheEntry = DistributedTableCacheEntry(relationId); List *shardList = NIL; int i = 0; for (i = 0; i < cacheEntry->shardIntervalArrayLength; i++) { ShardInterval *currentShardInterval = &cacheEntry->shardIntervalArray[i]; uint64 *shardIdPointer = AllocateUint64(currentShardInterval->shardId); shardList = lappend(shardList, shardIdPointer); } return shardList; }
List * GetSegmentList(void) { List *segments = NIL; SegmentConfigurationIterator iterator; Segment *current = NULL; InitIterateSegmentConfiguration(&iterator); while ((current = IterateSegmentConfiguration(&iterator))) { if (current->master || current->standby) continue; segments = lappend(segments, current); } return segments; }
/* * WaitForLockersMultiple * Wait until no transaction holds locks that conflict with the given * locktags at the given lockmode. * * To do this, obtain the current list of lockers, and wait on their VXIDs * until they are finished. * * Note we don't try to acquire the locks on the given locktags, only the VXIDs * of its lock holders; if somebody grabs a conflicting lock on the objects * after we obtained our initial list of lockers, we will not wait for them. */ void WaitForLockersMultiple(List *locktags, LOCKMODE lockmode) { List *holders = NIL; ListCell *lc; /* Done if no locks to wait for */ if (list_length(locktags) == 0) return; /* Collect the transactions we need to wait on */ foreach(lc, locktags) { LOCKTAG *locktag = lfirst(lc); holders = lappend(holders, GetLockConflicts(locktag, lockmode)); }
Node * mkdecl(Srcloc loc, Node *name, Type *ty) { Node *n; n = mknode(loc, Ndecl); n->decl.did = ndecls; n->decl.name = name; n->decl.type = ty; lappend(&decls, &ndecls, n); if (ty && hasparams(ty)) { n->decl.env = mkenv(); bindtype(n->decl.env, ty); } return n; }
/*--------------------------------------------------------------------- * DefineVirtualRelation * * Create the "view" relation. `DefineRelation' does all the work, * we just provide the correct arguments ... at least when we're * creating a view. If we're updating an existing view, we have to * work harder. *--------------------------------------------------------------------- */ static ObjectAddress DefineVirtualRelation(RangeVar *relation, List *tlist, bool replace, List *options) { Oid viewOid; LOCKMODE lockmode; CreateStmt *createStmt = makeNode(CreateStmt); List *attrList; ListCell *t; /* * create a list of ColumnDef nodes based on the names and types of the * (non-junk) targetlist items from the view's SELECT list. */ attrList = NIL; foreach(t, tlist) { TargetEntry *tle = (TargetEntry *) lfirst(t); if (!tle->resjunk) { ColumnDef *def = makeColumnDef(tle->resname, exprType((Node *) tle->expr), exprTypmod((Node *) tle->expr), exprCollation((Node *) tle->expr)); /* * It's possible that the column is of a collatable type but the * collation could not be resolved, so double-check. */ if (type_is_collatable(exprType((Node *) tle->expr))) { if (!OidIsValid(def->collOid)) ereport(ERROR, (errcode(ERRCODE_INDETERMINATE_COLLATION), errmsg("could not determine which collation to use for view column \"%s\"", def->colname), errhint("Use the COLLATE clause to set the collation explicitly."))); } else Assert(!OidIsValid(def->collOid)); attrList = lappend(attrList, def); } }
void rest_multi_init(MultiRestState *state, int nhandles) { int i; if (nhandles > MAX_CURL_HANDLES) elog(ERROR, "Number of curl handles (%d) is larger than max (%d)", nhandles, MAX_CURL_HANDLES); state->nhandles = nhandles; state->multi_handle = curl_multi_init(); state->available = nhandles; for (i = 0; i < nhandles; i++) { state->handles[i] = NULL; state->errorbuffs[i] = NULL; state->postDatas[i] = NULL; state->responses[i] = NULL; } MULTI_REST_STATES = lappend(MULTI_REST_STATES, state); }
static void pushIncompleteSplit(RelFileNode node, BlockNumber leftBlkno, BlockNumber rightBlkno, BlockNumber rootBlkno) { ginIncompleteSplit *split; MemoryContextSwitchTo(topCtx); split = palloc(sizeof(ginIncompleteSplit)); split->node = node; split->leftBlkno = leftBlkno; split->rightBlkno = rightBlkno; split->rootBlkno = rootBlkno; incomplete_splits = lappend(incomplete_splits, split); MemoryContextSwitchTo(opCtx); }
void DMLUtils::PrepareAbstractScanState(AbstractScanPlanState *ss_plan_state, const ScanState &ss_state) { // Resolve table Relation ss_relation_desc = ss_state.ss_currentRelation; ss_plan_state->table_oid = ss_relation_desc->rd_id; ss_plan_state->database_oid = Bridge::GetCurrentDatabaseOid(); // Copy qual auto qual_list = ss_state.ps.qual; ListCell *qual_item; ss_plan_state->qual = NIL; foreach (qual_item, qual_list) { ExprState *expr_state = (ExprState *)lfirst(qual_item); ExprState *expr_state_copy = CopyExprState(expr_state); ss_plan_state->qual = lappend(ss_plan_state->qual, expr_state_copy); }
static void parse_option(pgut_option *opt, char *arg) { opt->source = SOURCE_DEFAULT; /* -o can be specified many times */ if (arg && arg[0]) bulkload_options = lappend(bulkload_options, arg); if (pg_strcasecmp(arg, "TYPE=FUNCTION") == 0) type_function = true; if (pg_strcasecmp(arg, "TYPE=BINARY") == 0 || pg_strcasecmp(arg, "TYPE=FIXED") == 0) type_binary = true; if (pg_strcasecmp(arg, "WRITER=BINARY") == 0) writer_binary = true; }
static List * filterList(List *list, bool skip_spaces, bool qnames) { List *result = NIL; ListCell *cell; bool isdot = false; orafce_lexnode *a = NULL; orafce_lexnode *dot = NULL; foreach(cell, list) { orafce_lexnode *nd = (orafce_lexnode *) lfirst(cell); if (qnames) { isdot = (IsType(nd, OTHERS) && (nd->str[0] == '.')); if (IsType(nd, IDENT) && dot && a) { a = compose(a, nd); dot = NULL; continue; } else if (isdot && !dot && a) { dot = COPY_NODE(nd); continue; } else if (IsType(nd, IDENT) && !a) { a = COPY_NODE(nd); continue; } } /* clean buffered values */ APPEND_NODE(result,a); APPEND_NODE(result,dot); if (!(skip_spaces && IsType(nd, WHITESPACE))) { result = lappend(result, COPY_NODE(nd)); } }
int getplid (char *nam) { int fd7, high = 999, no; char *p, *p2; char name[80]; if (havepid != -1) return (havepid); /* already did it */ lflush (); /* flush any pending I/O */ sprintf (name, "%s\n", nam); /* append a \n to name */ if (lopen (playerids) < 0) /* no file, make it */ { if ((fd7 = _creat (playerids, _S_IWRITE)) < 0) return (-1); /* can't make it */ _close (fd7); goto addone; /* now append new playerid record to file */ } for (;;) /* now search for the name in the player id file */ { p = lgetl (); if (p == NULL) break; /* EOF? */ no = atoi (p); /* the id # */ p2 = lgetl (); if (p2 == NULL) break; /* EOF? */ if (no > high) high = no; /* accumulate highest id # */ if (strcmp (p2, name) == 0) /* we found him */ { return (no); /* his id number */ } } lrclose (); /* if we get here, we didn't find him in the file -- put him there */ addone: if (lappend (playerids) < 0) return (-1); /* can't open file for append */ lprintf ("%d\n%s", (int) ++high, name); /* new id # and name */ lwclose (); lcreat ((char *) 0); /* re-open terminal channel */ return (high); }
/* * Similar to logicalrep_worker_find(), but returns list of all workers for * the subscription, instead just one. */ List * logicalrep_workers_find(Oid subid, bool only_running) { int i; List *res = NIL; Assert(LWLockHeldByMe(LogicalRepWorkerLock)); /* Search for attached worker for a given subscription id. */ for (i = 0; i < max_logical_replication_workers; i++) { LogicalRepWorker *w = &LogicalRepCtx->workers[i]; if (w->in_use && w->subid == subid && (!only_running || w->proc)) res = lappend(res, w); } return res; }
/* * add_coltypes * * Given a target list, add the types the entries to a list of types seen * for the same column across all streams */ static void add_coltypes(StreamTargetsEntry *stream, List *targetlist) { ListCell *lc; foreach(lc, targetlist) { bool found; TypeCast *tc = (TypeCast *) lfirst(lc); StreamColumnsEntry *entry; char *name = FigureColname((Node *) tc); entry = (StreamColumnsEntry *) hash_search(stream->colstotypes, name, HASH_ENTER, &found); if (!found) entry->types = NIL; entry->types = lappend(entry->types, tc); }
/* Creates a list of cstrings from a single dimensional array object. */ static List * ArrayObjectToCStringList(ArrayType *arrayObject) { List *cstringList = NIL; Datum *datumArray = DeconstructArrayObject(arrayObject); int32 arraySize = ArrayObjectCount(arrayObject); int32 arrayIndex = 0; for (arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) { Datum datum = datumArray[arrayIndex]; char *cstring = TextDatumGetCString(datum); cstringList = lappend(cstringList, cstring); } Assert(cstringList != NIL); return cstringList; }
/* * LoadShardIntervalList returns a list of shard intervals related for a given * distributed table. The function returns an empty list if no shards can be * found for the given relation. */ List * LoadShardIntervalList(Oid relationId) { DistTableCacheEntry *cacheEntry = DistributedTableCacheEntry(relationId); List *shardList = NIL; int i = 0; for (i = 0; i < cacheEntry->shardIntervalArrayLength; i++) { ShardInterval *newShardInterval = NULL; newShardInterval = (ShardInterval *) palloc0(sizeof(ShardInterval)); CopyShardInterval(&cacheEntry->shardIntervalArray[i], newShardInterval); shardList = lappend(shardList, newShardInterval); } return shardList; }
/* Initialize a new line record. After the object has been parsed there * will be an extra line record which does not point to an object line. * So the display routine must take this into account and stop processing * at the last line record. It's easier to do things this way because the * program is not sure at a lines end if there will be another line in * the file or EOF. * * Return: * void */ void new_line_record (canon_info_t *ci, parse_info_t *pi, canon_line_t *lrec) { lrec->attr = F_NOATTR; lrec->count = 0; lrec->lines = 1; /* each "line" can have multiple lines due to '\' */ lrec->skip_attr = 0; /* set the beginning of line pointer */ if (ci->io == CANON_MEM) lrec->ptr = ci->linep = ci->bufp; else { lrec->fpos = ci->flinep = ftell (ci->fd); if (verbose) fprintf (dfile, "new_line_record (): num_lines (%d) beg line disk (%ld)\n", pi->num_lines, lrec->fpos); } if (ci->lio == CANON_DISK) lappend (lrec, ci); }
List * GetVirtualSegmentList(void) { #if 0 List *real_segments = GetSegmentList(); int real_segment_num = list_length(real_segments); Segment *dest; Segment *src; src = linitial(real_segments); dest = CopySegment(src); dest->id = real_segment_num; dest->dbid = real_segment_num + 1; return lappend(real_segments, dest); #else return GetSegmentList(); #endif }
/* * This variant of list_union() determines duplicates via simple * pointer comparison. */ List * list_union_ptr(const List *list1, const List *list2) { List *result; const ListCell *cell; Assert(IsPointerList(list1)); Assert(IsPointerList(list2)); result = list_copy(list1); foreach(cell, list2) { if (!list_member_ptr(result, lfirst(cell))) result = lappend(result, lfirst(cell)); } check_list_invariants(result); return result; }
/* * ActiveDistributedTransactionNumbers returns a list of pointers to * transaction numbers of distributed transactions that are in progress * and were started by the node on which it is called. */ List * ActiveDistributedTransactionNumbers(void) { List *activeTransactionNumberList = NIL; int curBackend = 0; /* build list of starting procs */ for (curBackend = 0; curBackend < MaxBackends; curBackend++) { PGPROC *currentProc = &ProcGlobal->allProcs[curBackend]; BackendData currentBackendData; uint64 *transactionNumber = NULL; if (currentProc->pid == 0) { /* unused PGPROC slot */ continue; } GetBackendDataForProc(currentProc, ¤tBackendData); if (!IsInDistributedTransaction(¤tBackendData)) { /* not a distributed transaction */ continue; } if (!currentBackendData.transactionId.transactionOriginator) { /* not a coordinator process */ continue; } transactionNumber = (uint64 *) palloc0(sizeof(uint64)); *transactionNumber = currentBackendData.transactionId.transactionNumber; activeTransactionNumberList = lappend(activeTransactionNumberList, transactionNumber); } return activeTransactionNumberList; }
/* Append a list of nodes from the jsonpath (jsonb_path_ops). */ static List * jsonb_path_ops__extract_nodes(JsonPathGinContext *cxt, JsonPathGinPath path, JsonbValue *scalar, List *nodes) { if (scalar) { /* append path hash node for equality queries */ uint32 hash = path.hash; JsonbHashScalarValue(scalar, &hash); return lappend(nodes, make_jsp_entry_node(UInt32GetDatum(hash))); } else { /* jsonb_path_ops doesn't support EXISTS queries => nothing to append */ return nodes; } }
/* * Tests that mdver_add_nuke_event adds an event when the last * event is not nuke */ void test__mdver_add_nuke_event_no_nuke(void **state) { /* Create an empty list of events */ List *events = NIL; /* Let's create some non-nuke event and add it to the list */ mdver_event *mdev = (mdver_event *) palloc0(sizeof(mdver_event)); mdev->key = 100; mdev->new_ddl_version = 1; mdev->new_dml_version = 2; events = lappend(events, mdev); /* Now add a nuke event */ mdver_add_nuke_event(&events); /* Adding the nuke increased the length, it should be 2 */ assert_int_equal(2 /* length */, length(events)); }
void test__opexpr_to_pxffilter__unary_expr(void **state) { PxfFilterDesc *filter = (PxfFilterDesc*) palloc0(sizeof(PxfFilterDesc)); OpExpr *expr = (OpExpr*) palloc0(sizeof(OpExpr)); Var *arg = (Var*) palloc0(sizeof(Var)); arg->xpr.type = T_Var; assert_false(opexpr_to_pxffilter(NULL, NULL)); assert_false(opexpr_to_pxffilter(NULL, filter)); assert_false(opexpr_to_pxffilter(expr, NULL)); expr->args = NIL; expr->args = lappend(expr->args, arg); assert_false(opexpr_to_pxffilter(expr, filter)); pfree(arg); pfree(filter); pfree(expr); }
/* * Convert text array to list of strings. * * Note: the resulting list of strings is pallocated here. */ static List * textarray_to_stringlist(ArrayType *textarray) { Datum *elems; int nelems, i; List *res = NIL; deconstruct_array(textarray, TEXTOID, -1, false, 'i', &elems, NULL, &nelems); if (nelems == 0) return NIL; for (i = 0; i < nelems; i++) res = lappend(res, makeString(TextDatumGetCString(elems[i]))); return res; }
/* * Handle table synchronization cooperation from the apply worker. * * Walk over all subscription tables that are individually tracked by the * apply process (currently, all that have state other than * SUBREL_STATE_READY) and manage synchronization for them. * * If there are tables that need synchronizing and are not being synchronized * yet, start sync workers for them (if there are free slots for sync * workers). To prevent starting the sync worker for the same relation at a * high frequency after a failure, we store its last start time with each sync * state info. We start the sync worker for the same relation after waiting * at least wal_retrieve_retry_interval. * * For tables that are being synchronized already, check if sync workers * either need action from the apply worker or have finished. This is the * SYNCWAIT to CATCHUP transition. * * If the synchronization position is reached (SYNCDONE), then the table can * be marked as READY and is no longer tracked. */ static void process_syncing_tables_for_apply(XLogRecPtr current_lsn) { struct tablesync_start_time_mapping { Oid relid; TimestampTz last_start_time; }; static List *table_states = NIL; static HTAB *last_start_times = NULL; ListCell *lc; bool started_tx = false; Assert(!IsTransactionState()); /* We need up-to-date sync state info for subscription tables here. */ if (!table_states_valid) { MemoryContext oldctx; List *rstates; ListCell *lc; SubscriptionRelState *rstate; /* Clean the old list. */ list_free_deep(table_states); table_states = NIL; StartTransactionCommand(); started_tx = true; /* Fetch all non-ready tables. */ rstates = GetSubscriptionNotReadyRelations(MySubscription->oid); /* Allocate the tracking info in a permanent memory context. */ oldctx = MemoryContextSwitchTo(CacheMemoryContext); foreach(lc, rstates) { rstate = palloc(sizeof(SubscriptionRelState)); memcpy(rstate, lfirst(lc), sizeof(SubscriptionRelState)); table_states = lappend(table_states, rstate); }
/* * Request worker for specified sub/rel to be stopped on commit. */ void logicalrep_worker_stop_at_commit(Oid subid, Oid relid) { int nestDepth = GetCurrentTransactionNestLevel(); LogicalRepWorkerId *wid; MemoryContext oldctx; /* Make sure we store the info in context that survives until commit. */ oldctx = MemoryContextSwitchTo(TopTransactionContext); /* Check that previous transactions were properly cleaned up. */ Assert(on_commit_stop_workers == NULL || nestDepth >= on_commit_stop_workers->nestDepth); /* * Push a new stack element if we don't already have one for the current * nestDepth. */ if (on_commit_stop_workers == NULL || nestDepth > on_commit_stop_workers->nestDepth) { StopWorkersData *newdata = palloc(sizeof(StopWorkersData)); newdata->nestDepth = nestDepth; newdata->workers = NIL; newdata->parent = on_commit_stop_workers; on_commit_stop_workers = newdata; } /* * Finally add a new worker into the worker list of the current * subtransaction. */ wid = palloc(sizeof(LogicalRepWorkerId)); wid->subid = subid; wid->relid = relid; on_commit_stop_workers->workers = lappend(on_commit_stop_workers->workers, wid); MemoryContextSwitchTo(oldctx); }
/* * This variant of list_difference() determines list membership via * simple pointer equality. */ List * list_difference_ptr(const List *list1, const List *list2) { const ListCell *cell; List *result = NIL; Assert(IsPointerList(list1)); Assert(IsPointerList(list2)); if (list2 == NIL) return list_copy(list1); foreach(cell, list1) { if (!list_member_ptr(list2, lfirst(cell))) result = lappend(result, lfirst(cell)); } check_list_invariants(result); return result; }
static Node *simpblob(Simp *s, Node *blob, Node ***l, size_t *nl) { Node *n, *d, *r; char lbl[128]; n = mkname(blob->line, genlblstr(lbl, 128)); d = mkdecl(blob->line, n, blob->expr.type); r = mkexpr(blob->line, Ovar, n, NULL); d->decl.init = blob; d->decl.type = blob->expr.type; d->decl.isconst = 1; htput(s->globls, d, strdup(lbl)); r->expr.did = d->decl.did; r->expr.type = blob->expr.type; r->expr.isconst = 1; lappend(l, nl, d); return r; }