int main () {
    int a1 = 1, a2 = 2, a3 = 3, a4 = 4;
    cons *list1, *list2;
    
    list_push(&list1, &a1);
    list_push(&list1, &a2);
    
    list_push(&list2, &a3);
    list_push(&list2, &a4);
    
    printf("list1:\n");
    print_list(list1);
    
    printf("list2:\n");
    print_list(list2);
    
    cons* testtt = NULL;
    list_concat(&testtt, &list1);
    printf("NULL+list1:\n");
    print_list(list1);
    
    list_concat(&list1, &list2);
    printf("list1+list2:\n");
    print_list(list1);
    
    testtt = NULL;
    list_concat(&list1, &testtt);
    printf("list1+NULL:\n");
    print_list(list1);
    
    printf("length of list1:\n");
    printf("%d\n", list_length(list1));
}
Example #2
0
/*
 * master_metadata_snapshot prints all the queries that are required
 * to generate a metadata snapshot.
 */
Datum
master_metadata_snapshot(PG_FUNCTION_ARGS)
{
	List *dropSnapshotCommands = MetadataDropCommands();
	List *createSnapshotCommands = MetadataCreateCommands();
	List *snapshotCommandList = NIL;
	ListCell *snapshotCommandCell = NULL;
	int snapshotCommandCount = 0;
	Datum *snapshotCommandDatumArray = NULL;
	ArrayType *snapshotCommandArrayType = NULL;
	int snapshotCommandIndex = 0;
	Oid ddlCommandTypeId = TEXTOID;

	snapshotCommandList = list_concat(snapshotCommandList, dropSnapshotCommands);
	snapshotCommandList = list_concat(snapshotCommandList, createSnapshotCommands);

	snapshotCommandCount = list_length(snapshotCommandList);
	snapshotCommandDatumArray = palloc0(snapshotCommandCount * sizeof(Datum));

	foreach(snapshotCommandCell, snapshotCommandList)
	{
		char *metadataSnapshotCommand = (char *) lfirst(snapshotCommandCell);
		Datum metadataSnapshotCommandDatum = CStringGetTextDatum(metadataSnapshotCommand);

		snapshotCommandDatumArray[snapshotCommandIndex] = metadataSnapshotCommandDatum;
		snapshotCommandIndex++;
	}
Example #3
0
/*
 * transformTargetList()
 * Turns a list of ResTarget's into a list of TargetEntry's.
 *
 * This code acts mostly the same for SELECT, UPDATE, or RETURNING lists;
 * the main thing is to transform the given expressions (the "val" fields).
 * The exprKind parameter distinguishes these cases when necesssary.
 */
List *
transformTargetList(ParseState *pstate, List *targetlist,
					ParseExprKind exprKind)
{
	List	   *p_target = NIL;
	ListCell   *o_target;

	/* Shouldn't have any leftover multiassign items at start */
	Assert(pstate->p_multiassign_exprs == NIL);

	foreach(o_target, targetlist)
	{
		ResTarget  *res = (ResTarget *) lfirst(o_target);

		/*
		 * Check for "something.*".  Depending on the complexity of the
		 * "something", the star could appear as the last field in ColumnRef,
		 * or as the last indirection item in A_Indirection.
		 */
		if (IsA(res->val, ColumnRef))
		{
			ColumnRef  *cref = (ColumnRef *) res->val;

			if (IsA(llast(cref->fields), A_Star))
			{
				/* It is something.*, expand into multiple items */
				p_target = list_concat(p_target,
									   ExpandColumnRefStar(pstate, cref,
														   true));
				continue;
			}
		}
		else if (IsA(res->val, A_Indirection))
		{
			A_Indirection *ind = (A_Indirection *) res->val;

			if (IsA(llast(ind->indirection), A_Star))
			{
				/* It is something.*, expand into multiple items */
				p_target = list_concat(p_target,
									   ExpandIndirectionStar(pstate, ind,
															 true, exprKind));
				continue;
			}
		}

		/*
		 * Not "something.*", so transform as a single expression
		 */
		p_target = lappend(p_target,
						   transformTargetEntry(pstate,
												res->val,
												NULL,
												exprKind,
												res->name,
												false));
	}
Example #4
0
/*
 * transformTargetList()
 * Turns a list of ResTarget's into a list of TargetEntry's.
 *
 * At this point, we don't care whether we are doing SELECT, INSERT,
 * or UPDATE; we just transform the given expressions (the "val" fields).
 */
List *
transformTargetList(ParseState *pstate, List *targetlist)
{
	List	   *p_target = NIL;
	ListCell   *o_target;

	foreach(o_target, targetlist)
	{
		ResTarget  *res = (ResTarget *) lfirst(o_target);

		/*
		 * Check for "something.*".  Depending on the complexity of the
		 * "something", the star could appear as the last name in ColumnRef,
		 * or as the last indirection item in A_Indirection.
		 */
		if (IsA(res->val, ColumnRef))
		{
			ColumnRef  *cref = (ColumnRef *) res->val;

			if (strcmp(strVal(llast(cref->fields)), "*") == 0)
			{
				/* It is something.*, expand into multiple items */
				p_target = list_concat(p_target,
									   ExpandColumnRefStar(pstate, cref,
														   true));
				continue;
			}
		}
		else if (IsA(res->val, A_Indirection))
		{
			A_Indirection *ind = (A_Indirection *) res->val;
			Node	   *lastitem = llast(ind->indirection);

			if (IsA(lastitem, String) &&
				strcmp(strVal(lastitem), "*") == 0)
			{
				/* It is something.*, expand into multiple items */
				p_target = list_concat(p_target,
									   ExpandIndirectionStar(pstate, ind,
															 true));
				continue;
			}
		}

		/*
		 * Not "something.*", so transform as a single expression
		 */
		p_target = lappend(p_target,
						   transformTargetEntry(pstate,
												res->val,
												NULL,
												res->name,
												false));
	}
Example #5
0
File: app.c Project: MurphyMc/sts
struct list_res
reachability (const struct hs *hs, uint32_t port, const uint32_t *out, int nout)
{
  struct res *in = res_create (data_file->stages + 1);
  struct list_res res = {0};
  hs_copy (&in->hs, hs);
  in->port = port;
  list_append (&queues[ntf_get_sw (in->port)], in);

  int n = data_file->ntfs - 1;
  struct tdata data[n];
  memset (data, 0, sizeof data);

  g_out = out;
  g_nout = nout;

  for (int i = 0; i < n; i++) {
    struct tdata *p = &data[i];
    p->sw = i;
    pthread_create (&p->tid, NULL, reach_thread, p);
  }
  for (int i = 0; i < n; i++) {
    pthread_join (data[i].tid, NULL);
    list_concat (&res, &data[i].res);
  }

  return res;
}
Example #6
0
struct list_res
reachability (const uint32_t *out, int nout, int hop_count, bool find_loop,
	      array_t * out_arr)
{
  struct list_res res = {0};
  int n = data_file->ntfs - 1;
  struct tdata data[n];
  memset (data, 0, sizeof data);

  g_out = out;
  g_nout = nout;
  g_hop_count = hop_count;
  g_find_loop = find_loop;
  g_out_arr   = out_arr;

  for (int i = 0; i < n; i++) {
    struct tdata *p = &data[i];
    p->sw = i;
    pthread_create (&p->tid, NULL, reach_thread, p);
  }
  for (int i = 0; i < n; i++) {
    pthread_join (data[i].tid, NULL);
    list_concat (&res, &data[i].res);
  }

  return res;
}
Example #7
0
void worker_push(LPWORKER lpWorker)
{
  BOOL bFreeWorker;

  bFreeWorker = TRUE;

  WaitForSingleObject(hWorkersMutex, INFINITE);
  DEBUG_PRINT("Testing if we are under the maximum number of running workers");
  if (list_length((LPLIST)lpWorkers) < THREAD_WORKERS_MAX)
  {
    DEBUG_PRINT("Saving this worker for future use");
    DEBUG_PRINT("Next: %x", ((LPLIST)lpWorker)->lpNext);
    lpWorkers = (LPWORKER)list_concat((LPLIST)lpWorker, (LPLIST)lpWorkers);
    bFreeWorker = FALSE;
  };
  nWorkersCurrent--;
  DEBUG_PRINT("Workers running current/runnning max/waiting: %d/%d/%d",
      nWorkersCurrent,
      nWorkersMax,
      list_length((LPLIST)lpWorkers));
  ReleaseMutex(hWorkersMutex);

  if (bFreeWorker)
  {
    DEBUG_PRINT("Freeing worker %x", lpWorker);
    worker_free(lpWorker);
  }
}
Example #8
0
File: ntf.c Project: NetSys/sts
struct list_res
ntf_apply (const struct res *in, int sw)
{
  struct tf *tf = tf_get (sw + 1);

  struct list_res queue = tf_apply (tf, in, false);
  for (int i = 0; i < data_file->stages - 1; i++) {
    struct list_res nextq = {0};
    for (struct res *cur = queue.head; cur; cur = cur->next) {
      struct list_res tmp = tf_apply (tf, cur, true);
      list_concat (&nextq, &tmp);
    }
    list_res_free (&queue);
    queue = nextq;
  }

  struct res *cur = queue.head, *prev = NULL;
  while (cur) {
    int p = in->port + OUTPUT_ID;
    if (cur->port == p) list_remove (&queue, cur, prev, res_free);
    else { prev = cur; cur = cur->next; }
  }

  return queue;
}
Example #9
0
struct list_res
res_walk_parents (const struct res *out, const struct hs *hs, int in_port,
		  array_t* out_arr)
{
  struct res *curr_res = (struct res*) out;
  struct list_res currq = {0};

  // set up initial result to start inversion
  struct hs int_hs;
  hs_isect_arr (&int_hs, &out->hs, out_arr);
  list_append (&currq, res_extend (out, &int_hs, out->port, true));

  struct res *cur;

  while (curr_res) {
    if (curr_res->rules.cur) {
      for (int i = curr_res->rules.cur - 1; i >= 0; i--) {
	struct list_res nextq = {0};
	struct res_rule r = curr_res->rules.arr[i];
	while ((cur = currq.head)) {
	  list_pop (&currq);
	  struct list_res tmp = rule_inv_apply (r.tf_tf, r.tf_rule, cur, false);
	  list_concat (&nextq, &tmp);
	  res_free (cur);
	} // for each current result from rule inversion
	currq = nextq;
      } // for each rule
    }
    else return currq;

    // set (hs,port) which the inverted (hs,port) results must intersect
    struct res *parent = curr_res->parent;
    struct hs *next_hs = hs_create (curr_res->hs.len);
    int next_port;
    if (parent) {
      hs_copy (next_hs, &parent->hs);
      next_port = parent->port;
    }
    else {
      hs_copy (next_hs, hs);
      next_port = in_port;
    }

    // Intersect the results in `currq` with the target (hs,port)
    struct list_res nextq = {0};
    while ((cur = currq.head)) {
      list_pop (&currq);
      struct hs *new_hs = hs_isect_a (&cur->hs, next_hs);
      if (cur->port == next_port && new_hs)
	list_append (&nextq, res_extend (cur, new_hs, next_port, false));
      else
	res_free (cur);
    }
    currq = nextq;
    curr_res = parent;
  }

  return currq;
}
Example #10
0
void list_copy(list_t *destiny, list_t *source)
{
    /* No point in copying a list to itself. */
    if (destiny != source){
        list_empty(destiny);
        list_concat(destiny, source);
    }
}
Example #11
0
File: kt_fdw.c Project: gugu/kt_fdw
    static void
getTableOptions(Oid foreigntableid,struct ktTableOptions *table_options)
{
    ForeignTable *table;
    ForeignServer *server;
    UserMapping *mapping;
    List	   *options;
    ListCell   *lc;

#ifdef DEBUG
    elog(NOTICE, "getTableOptions");
#endif

    /*
     * Extract options from FDW objects. We only need to worry about server
     * options for Redis
     *
     */
    table = GetForeignTable(foreigntableid);
    server = GetForeignServer(table->serverid);
    mapping = GetUserMapping(GetUserId(), table->serverid);

    table_options->userId = mapping->userid;
    table_options->serverId = server->serverid;

    options = NIL;
    options = list_concat(options, table->options);
    options = list_concat(options, server->options);
    options = list_concat(options, mapping->options);

    //	table_options->table_type = PG_REDIS_SCALAR_TABLE;

    /* Loop through the options, and get the server/port */
    foreach(lc, options)
    {
        DefElem    *def = (DefElem *) lfirst(lc);

        if (strcmp(def->defname, "host") == 0)
            table_options->host = defGetString(def);

        if (strcmp(def->defname, "port") == 0)
            table_options->port = atoi(defGetString(def));

        if (strcmp(def->defname, "timeout") == 0)
            table_options->timeout = atoi(defGetString(def));
    }
Example #12
0
/*
 * pxf_make_expression_items_list
 *
 * Given a scan node qual list, find the filters that are eligible to be used
 * by PXF, construct an expressions list, which consists of OpExpr or BoolExpr nodes
 * and return it to the caller.
 *
 * Basically this function just transforms expression tree to Reversed Polish Notation list.
 *
 *
 */
static List *
pxf_make_expression_items_list(List *quals, Node *parent, int *logicalOpsNum)
{
	ExpressionItem *expressionItem = NULL;
	List			*result = NIL;
	ListCell		*lc = NULL;
	ListCell		*ilc = NULL;
	
	if (list_length(quals) == 0)
		return NIL;

	foreach (lc, quals)
	{
		Node *node = (Node *) lfirst(lc);
		NodeTag tag = nodeTag(node);
		expressionItem = (ExpressionItem *) palloc0(sizeof(ExpressionItem));
		expressionItem->node = node;
		expressionItem->parent = parent;
		expressionItem->processed = false;

		switch (tag)
		{
			case T_OpExpr:
			case T_NullTest:
			{
				result = lappend(result, expressionItem);
				break;
			}
			case T_BoolExpr:
			{
				(*logicalOpsNum)++;
				BoolExpr	*expr = (BoolExpr *) node;
				List *inner_result = pxf_make_expression_items_list(expr->args, node, logicalOpsNum);
				result = list_concat(result, inner_result);

				int childNodesNum = 0;

				/* Find number of child nodes on first level*/
				foreach (ilc, inner_result)
				{
					ExpressionItem *ei = (ExpressionItem *) lfirst(ilc);
					if (!ei->processed && ei->parent == node)
					{
						ei->processed = true;
						childNodesNum++;
					}
				}

				for (int i = 0; i < childNodesNum - 1; i++)
				{
					result = lappend(result, expressionItem);
				}
				break;
			}
			default:
				elog(DEBUG1, "pxf_make_expression_items_list: unsupported node tag %d", tag);
				break;
		}
Example #13
0
/*
 * pxf_make_filter_list
 *
 * Given a scan node qual list, find the filters that are eligible to be used
 * by PXF, construct a PxfFilterDesc list that describes the filter information,
 * and return it to the caller.
 *
 * Caller is responsible for pfreeing the returned PxfFilterDesc List.
 */
static List *
pxf_make_filter_list(List *quals)
{
	List			*result = NIL;
	ListCell		*lc = NULL;
	
	if (list_length(quals) == 0)
		return NIL;

	/*
	 * Iterate over all implicitly ANDed qualifiers and add the ones
	 * that are supported for push-down into the result filter list.
	 */
	foreach (lc, quals)
	{
		Node *node = (Node *) lfirst(lc);
		NodeTag tag = nodeTag(node);

		switch (tag)
		{
			case T_OpExpr:
			{
				OpExpr			*expr 	= (OpExpr *) node;
				PxfFilterDesc	*filter;

				filter = (PxfFilterDesc *) palloc0(sizeof(PxfFilterDesc));
				elog(DEBUG5, "pxf_make_filter_list: node tag %d (T_OpExpr)", tag);

				if (opexpr_to_pxffilter(expr, filter))
					result = lappend(result, filter);
				else
					pfree(filter);

				break;
			}
			case T_BoolExpr:
			{
				BoolExpr	*expr = (BoolExpr *) node;
				BoolExprType boolType = expr->boolop;
				elog(DEBUG5, "pxf_make_filter_list: node tag %d (T_BoolExpr), bool node type %d %s",
						tag, boolType, boolType==AND_EXPR ? "(AND_EXPR)" : "");

				/* only AND_EXPR is supported */
				if (expr->boolop == AND_EXPR)
				{
					List *inner_result = pxf_make_filter_list(expr->args);
					elog(DEBUG5, "pxf_make_filter_list: inner result size %d", list_length(inner_result));
					result = list_concat(result, inner_result);
				}
				break;
			}
			default:
				/* expression not supported. ignore */
				elog(DEBUG5, "pxf_make_filter_list: unsupported node tag %d", tag);
				break;
		}
	}
Example #14
0
	foreach(joinCell, joinList)
	{
		JoinExpr *joinExpr = (JoinExpr *) lfirst(joinCell);
		List *onClauseList = list_copy((List *) joinExpr->quals);
		List *joinClauseList = list_copy((List *) joinExpr->quals);
		JoinType joinType = joinExpr->jointype;
		RangeTblRef *nextRangeTableRef = NULL;
		TableEntry *nextTable = NULL;
		JoinOrderNode *nextJoinNode = NULL;
		Node *rightArg = joinExpr->rarg;

		/* get the table on the right hand side of the join */
		if (IsA(rightArg, RangeTblRef))
		{
			nextRangeTableRef = (RangeTblRef *) rightArg;
		}
		else
		{
			ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
							errmsg("cannot perform distributed planning on this query"),
							errdetail("Subqueries in outer joins are not supported")));
		}

		nextTable = FindTableEntry(tableEntryList, nextRangeTableRef->rtindex);

		if (joinType == JOIN_INNER)
		{
			/* also consider WHERE clauses for INNER joins */
			joinClauseList = list_concat(joinClauseList, joinWhereClauseList);
		}

		/* find the best join rule type */
		nextJoinNode = EvaluateJoinRules(joinedTableList, currentJoinNode,
										 nextTable, joinClauseList, joinType);

		if (nextJoinNode->joinRuleType >= SINGLE_HASH_PARTITION_JOIN)
		{
			/* re-partitioning for OUTER joins is not implemented */
			ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
							errmsg("cannot run outer join query if join is not on the "
								   "partition column"),
							errdetail("Outer joins requiring repartitioning are not "
									  "supported.")));
		}

		if (joinType != JOIN_INNER)
		{
			/* preserve non-join clauses for OUTER joins */
			nextJoinNode->joinClauseList = onClauseList;
		}

		/* add next node to the join order */
		joinOrderList = lappend(joinOrderList, nextJoinNode);
		joinedTableList = lappend(joinedTableList, nextTable);
		currentJoinNode = nextJoinNode;
	}
Example #15
0
/*
 * RemoteCopy_GetRelationLoc
 * Get relation node list based on COPY data involved. An empty list is
 * returned to caller if relation involved has no locator information
 * as it is the case of a system relation.
 */
void
RemoteCopy_GetRelationLoc(RemoteCopyData *state,
						  Relation rel,
                          List *attnums)
{
	ExecNodes  *exec_nodes = NULL;

	/*
	 * If target table does not exists on nodes (e.g. system table)
	 * the location info returned is NULL. This is the criteria, when
	 * we need to run COPY on Coordinator
	 */
	state->rel_loc = GetRelationLocInfo(RelationGetRelid(rel));

	if (state->rel_loc)
	{
		/*
		 * Pick up one node only
		 * This case corresponds to a replicated table with COPY TO
		 *
		 */
		exec_nodes = makeNode(ExecNodes);
		if (!state->is_from &&
			IsLocatorReplicated(state->rel_loc->locatorType))
			exec_nodes->nodeList = GetPreferredReplicationNode(state->rel_loc->nodeList);
		else
		{
			/* All nodes necessary */
			exec_nodes->nodeList = list_concat(exec_nodes->nodeList, state->rel_loc->nodeList);
		}
	}

	state->idx_dist_by_col = -1;
	if (state->rel_loc && state->rel_loc->partAttrNum != 0)
	{
		/*
		 * Find the column used as key for data distribution.
		 * First scan attributes of tuple descriptor with the list
		 * of attributes used in COPY if any list is specified.
		 * If no list is specified, set this value to the one of
		 * locator information.
		 */
		if (attnums != NIL)
		{
			ListCell   *cur;
			foreach(cur, attnums)
			{
				int attnum = lfirst_int(cur);

				if (state->rel_loc->partAttrNum == attnum)
				{
					state->idx_dist_by_col = attnum - 1;
					break;
				}
			}
		}
Example #16
0
/*
 * GetTableDDLEvents takes in a relationId, includeSequenceDefaults flag,
 * and returns the list of DDL commands needed to reconstruct the relation.
 * When the flag includeSequenceDefaults is set, the function also creates
 * DEFAULT clauses for columns getting their default values from a sequence.
 * These DDL commands are all palloced; and include the table's schema
 * definition, optional column storage and statistics definitions, and index
 * and constraint definitions.
 */
List *
GetTableDDLEvents(Oid relationId, bool includeSequenceDefaults)
{
	List *tableDDLEventList = NIL;
	List *tableCreationCommandList = NIL;
	List *indexAndConstraintCommandList = NIL;
	List *replicaIdentityEvents = NIL;

	tableCreationCommandList = GetTableCreationCommands(relationId,
														includeSequenceDefaults);
	tableDDLEventList = list_concat(tableDDLEventList, tableCreationCommandList);

	indexAndConstraintCommandList = GetTableIndexAndConstraintCommands(relationId);
	tableDDLEventList = list_concat(tableDDLEventList, indexAndConstraintCommandList);

	replicaIdentityEvents = GetTableReplicaIdentityCommand(relationId);
	tableDDLEventList = list_concat(tableDDLEventList, replicaIdentityEvents);

	return tableDDLEventList;
}
Example #17
0
int main(/*int argc, char **argv*/) {
    int v0 = 0, v1 = 1, v2 = 1, v3 = 2, v4 = 3, v5 = 5, v6 = 8, v7 = 13;
    ImmutableListNode *list = list_create(8, 
                                      0, &v0,
                                      0, &v1,
                                      0, &v2,
                                      0, &v3,
                                      0, &v4,
                                      0, &v5,
                                      0, &v6,
                                      0, &v7);
    ImmutableListNode *old;
    old = list;
    ImmutableListNode *orig = list_head(list);
    list_free(old);

    // test prepend
    printf("Testing Prepend:\n");
    printf("length before: %d\n", list->length);
    int pref = 42;
    old = list;
    list = list_prepend(list, 0, &pref);
    printf("prev->head: %p, free old: %p\n", old, list_free(old));
    printf("length after: %d\n", list->length);

    // test append
    printf("Testing Append (2x):\n");
    printf("length before: %d\n", list->length);
    int aff = 21;
    old = list;
    list = list_append(list, 0, &aff);
    printf("length after 1x: %d\n", list->length);
    old = list;
    list = list_append(list, 0, &aff);
    printf("length after 2x: %d\n", list->length);

    // test concat
    printf("Testing Concatenation:\n");
    printf("length a: %d, length b: %d\n", orig->length, list->length);
    ImmutableListNode *cattd = list_concat(orig, list);

    printf("orig: \n");
    list_dump(stdout, orig);
    printf("list: \n");
    list_dump(stdout, list);
    printf("cattd: \n");
    list_dump(stdout, cattd);

    printf("free cattd: %p\n", list_free(cattd));
    printf("free list: %p\n", list_free(list));
    printf("free orig: %p\n", list_free(orig));

    return 0;
}
Example #18
0
/*
 * Parse and plan a querystring.
 *
 * At entry, plan->argtypes and plan->nargs must be valid.
 *
 * Query and plan lists are stored into *plan.
 */
static void
_SPI_prepare_plan(const char *src, _SPI_plan *plan)
{
	List	   *raw_parsetree_list;
	List	   *query_list_list;
	List	   *plan_list;
	ListCell   *list_item;
	ErrorContextCallback spierrcontext;
	Oid		   *argtypes = plan->argtypes;
	int			nargs = plan->nargs;

	/*
	 * Increment CommandCounter to see changes made by now.  We must do
	 * this to be sure of seeing any schema changes made by a just-preceding
	 * SPI command.  (But we don't bother advancing the snapshot, since the
	 * planner generally operates under SnapshotNow rules anyway.)
	 */
	CommandCounterIncrement();

	/*
	 * Setup error traceback support for ereport()
	 */
	spierrcontext.callback = _SPI_error_callback;
	spierrcontext.arg = (void *) src;
	spierrcontext.previous = error_context_stack;
	error_context_stack = &spierrcontext;

	/*
	 * Parse the request string into a list of raw parse trees.
	 */
	raw_parsetree_list = pg_parse_query(src);

	/*
	 * Do parse analysis and rule rewrite for each raw parsetree.
	 *
	 * We save the querytrees from each raw parsetree as a separate
	 * sublist.  This allows _SPI_execute_plan() to know where the
	 * boundaries between original queries fall.
	 */
	query_list_list = NIL;
	plan_list = NIL;

	foreach(list_item, raw_parsetree_list)
	{
		Node	   *parsetree = (Node *) lfirst(list_item);
		List	   *query_list;

		query_list = pg_analyze_and_rewrite(parsetree, argtypes, nargs);

		query_list_list = lappend(query_list_list, query_list);

		plan_list = list_concat(plan_list,
								pg_plan_queries(query_list, NULL, false));
	}
void test_concat_append_add_union_intersection_difference(void)
{     
     List list1 = list_random(MAX_LIST_SIZE, ELEMENT_MAX_VALUE);
     list_sort_by_item(&list1);
     list_unique(&list1);
     printf("Original List 1 ::: ");
     list_print(&list1);

     List list2 = list_random(MAX_LIST_SIZE, ELEMENT_MAX_VALUE);
     list_sort_by_item(&list2);
     list_unique(&list2);
     printf("%sOriginal List 2 ::: ", brown);
     list_print(&list2);

     List concat = list_concat(&list1, &list2);
     printf("%sConcatenation List ::: ", cyan);
     list_print(&concat);

     List append = list_duplicate(&list1);
     list_append(&append, &list2);
     printf("%sList 1 appended to list 2 ::: ", magenta);
     list_print(&append);
     
     List add = list_duplicate(&list1);
     list_add(&add, &list2);
     printf("%sList 1 added to list 2 ::: ", green);
     list_print(&add);

     List union_list = list_union(&list1, &list2);	
     printf("%sList Union ::: ", blue);
     list_print(&union_list);

     List intersection_list = list_intersection(&list1, &list2);
     printf("%sList Intersection ::: ", red);
     list_print(&intersection_list);

     List difference_list = list_difference(&list1, &list2);
     printf("%sDifference List ::: ", cyan);
     list_print(&difference_list);

     uint union_size = list_union_size(&list1, &list2);
     printf("%sList Union Size = %d\n", brown, union_size);

     uint intersection_size = list_intersection_size(&list1, &list2);
     printf("%sList Intersection Size = %d\n", black, intersection_size);

     uint difference_size = list_difference_size(&list1, &list2);
     printf("%sList Difference Size = %d\n", black, difference_size);
     
     printf("%s",none);

}
Example #20
0
static void
getTableOptions(Oid foreigntableid, struct wdbTableOptions *table_options) {
    ForeignTable*       table;
    ForeignServer*      server;
    UserMapping*        mapping;
    List*               options = NIL;
    ListCell*           lc = NULL;

#ifdef DEBUG
    elog(NOTICE, "getTableOptions");
#endif

    /*
     * Extract options from FDW objects.
     *
     */
    table = GetForeignTable(foreigntableid);
    server = GetForeignServer(table->serverid);
    mapping = GetUserMapping(GetUserId(), table->serverid);

    table_options->userId = mapping->userid;
    table_options->serverId = server->serverid;

    options = NIL;
    options = list_concat(options, table->options);
    options = list_concat(options, server->options);
    options = list_concat(options, mapping->options);

    /* Loop through the options, and get the server/port */
    foreach(lc, options)
        {
        DefElem    *def = (DefElem *) lfirst(lc);

        if (strcmp(def->defname, "address") == 0)
            table_options->address = defGetString(def);

        if (strcmp(def->defname, "size") == 0)
            table_options->size = atoi(defGetString(def));
    }
Example #21
0
/*
 * xfrm_tgt_list()
 * Turns a list of ResTarget's into a list of TargetEntry's.
 *
 * At this point, we don't care whether we are doing SELECT, INSERT,
 * or UPDATE; we just transform the given expressions (the "val" fields).
 */
struct list* xfrm_tgt_list(parse_state_s* pstate, struct list* targetlist)
{
	struct list *p_target = NIL;
	struct list_cell *o_target;

	foreach(o_target, targetlist) {
		ResTarget *res = (ResTarget *) lfirst(o_target);

		/*
		 * Check for "something.*".  Depending on the complexity of the
		 * "something", the star could appear as the last field in ColumnRef,
		 * or as the last indirection item in A_Indirection.
		 */
		if (IS_A(res->val, ColumnRef)) {
			column_ref_n *cref;

			cref = (column_ref_n *) res->val;
			if (IS_A(llast(cref->fields), A_Star)) {
				/* It is something.*, expand into multiple items */
				p_target = list_concat(p_target, ExpandColumnRefStar(pstate, cref, true));
				continue;
			}
		} else if (IS_A(res->val, A_Indirection)) {
			A_Indirection *ind;

			ind = (A_Indirection*) res->val;
			if (IS_A(llast(ind->indirection), A_Star)) {
				/* It is something.*, expand into multiple items */
				p_target = list_concat(p_target, ExpandIndirectionStar(pstate, ind, true));
				continue;
			}
		}

		/*
		 * Not "something.*", so transform as a single expression
		 */
		p_target = lappend(p_target, xfrm_tgt_entry(pstate, res->val, NULL, res->name, false));
	}
Example #22
0
static javaFdwExecutionState* javaGetOptions(Oid foreigntableid) {
	ForeignTable	*f_table;
	ForeignServer	*f_server;
	UserMapping	*f_mapping;
	List		*options;
	ListCell	*cell;
    jobject obj, res, serverClass;
    jmethodID serverConstructor;
    jclass cl;
    javaFdwExecutionState *state;
    char *classname = NULL;
    
	options = NIL;
	f_table = GetForeignTable(foreigntableid);
	options = list_concat(options, f_table->options);

	f_server = GetForeignServer(f_table->serverid);	
	options = list_concat(options, f_server->options);

	PG_TRY();
	{
		f_mapping = GetUserMapping(GetUserId(), f_table->serverid);
		options = list_concat(options, f_mapping->options);
	}
	PG_CATCH();
	{
		FlushErrorState();
		/* DO NOTHING HERE */
	}
	PG_END_TRY();
	

	foreach(cell, options) {
		DefElem *def = (DefElem *) lfirst(cell);
        if (strcmp(def->defname, "class") == 0) {
            classname = (char *) defGetString(def);
        }
    }
Example #23
0
File: tf.c Project: NetSys/sts
struct list_res
tf_apply (const struct tf *tf, const struct res *in, bool append)
{
  assert (in->hs.len == data_arrs_len);
  uint32_t app[MAX_APP];
  int napp = 0;
  struct list_res res = {0};

  const struct port_map_elem *rules = rule_get (tf, in->port);
  if (!rules) return res;

  if (rules->start != UINT32_MAX) {
    for (uint32_t cur = rules->start; cur < tf->nrules; cur++) {
      const struct rule *r = &tf->rules[cur];
      assert (r->in > 0);
      if (r->in != in->port) break;

      struct list_res tmp;
      tmp = rule_apply (r, tf, in, append, app, &napp);
      list_concat (&res, &tmp);
    }
  }

  /* Check all rules with multiple ports. */
  for (int i = 0; i < tf->nrules; i++) {
    const struct rule *r = &tf->rules[i];
    if (r->in >= 0) break;
    if (!port_match (in->port, r->in, tf)) continue;

    struct list_res tmp;
    tmp = rule_apply (r, tf, in, append, app, &napp);
    list_concat (&res, &tmp);
  }

  return res;
}
Example #24
0
/*
 * AtSubCommit_Notify() --- Take care of subtransaction commit.
 *
 * Reassign all items in the pending notifies list to the parent transaction.
 */
void
AtSubCommit_Notify(void)
{
	List	   *parentPendingNotifies;

	parentPendingNotifies = (List *) linitial(upperPendingNotifies);
	upperPendingNotifies = list_delete_first(upperPendingNotifies);

	Assert(list_length(upperPendingNotifies) ==
		   GetCurrentTransactionNestLevel() - 2);

	/*
	 * We could try to eliminate duplicates here, but it seems not worthwhile.
	 */
	pendingNotifies = list_concat(parentPendingNotifies, pendingNotifies);
}
Example #25
0
/*
 * pglogBeginForeignScan
 *		Initiate access to the log by creating CopyState
 */
static void
pglogBeginForeignScan(ForeignScanState *node, int eflags)
{
	ForeignScan *plan = (ForeignScan *) node->ss.ps.plan;
	PgLogExecutionState *festate;

	elog(DEBUG1,"Entering function %s",__func__);

	/*
	 * Do nothing in EXPLAIN (no ANALYZE) case.  node->fdw_state stays NULL.
	 */
	if (eflags & EXEC_FLAG_EXPLAIN_ONLY)
		return;

	/* Initialise the execution state */
	festate = (PgLogExecutionState *) palloc(sizeof(PgLogExecutionState));
	festate->filenames = initLogFileNames(Pglog_directory);
	festate->i = 0;

	/* Forces CSV format */
	festate->options = list_make1(makeDefElem("format", (Node *) makeString("csv")));

	/* Add any options from the plan (currently only convert_selectively) */
	festate->options = list_concat(festate->options, plan->fdw_private);

	/* Remember scan memory context */
	festate->scan_cxt = CurrentMemoryContext;

	/*
	 * Create CopyState from FDW options.  We always acquire all columns, so
	 * as to match the expected ScanTupleSlot signature.
	 * Starts from the first file in the list.
	 */
	festate->cstate = NULL;
	BeginNextCopy(node->ss.ss_currentRelation, festate);
	elog(DEBUG1,"Copy state %p",festate->cstate);

	/*
	 * Save state in node->fdw_state.  We must save enough information to call
	 * BeginCopyFrom() again.
	 */

	node->fdw_state = (void *) festate;
}
Example #26
0
/*
 * Pull up children of a UNION node that are identically-propertied UNIONs.
 *
 * NOTE: we can also pull a UNION ALL up into a UNION, since the distinct
 * output rows will be lost anyway.
 */
static List *
recurse_union_children(Node *setOp, PlannerInfo *root,
					   double tuple_fraction,
					   SetOperationStmt *top_union,
					   List *refnames_tlist)
{
	List	   *child_sortclauses;

	if (IsA(setOp, SetOperationStmt))
	{
		SetOperationStmt *op = (SetOperationStmt *) setOp;

		if (op->op == top_union->op &&
			(op->all == top_union->all || op->all) &&
			equal(op->colTypes, top_union->colTypes))
		{
			/* Same UNION, so fold children into parent's subplan list */
			return list_concat(recurse_union_children(op->larg, root,
													  tuple_fraction,
													  top_union,
													  refnames_tlist),
							   recurse_union_children(op->rarg, root,
													  tuple_fraction,
													  top_union,
													  refnames_tlist));
		}
	}

	/*
	 * Not same, so plan this child separately.
	 *
	 * Note we disallow any resjunk columns in child results.  This is
	 * necessary since the Append node that implements the union won't do any
	 * projection, and upper levels will get confused if some of our output
	 * tuples have junk and some don't.  This case only arises when we have an
	 * EXCEPT or INTERSECT as child, else there won't be resjunk anyway.
	 */
	return list_make1(recurse_set_operations(setOp, root,
											 tuple_fraction,
											 top_union->colTypes, false,
											 -1, refnames_tlist,
											 &child_sortclauses));
}
Example #27
0
struct list *files_from_bundles(struct list *bundles)
{
	struct list *files = NULL;
	struct list *list;
	struct manifest *bundle;

	list = list_head(bundles);
	while (list) {
		struct list *bfiles;
		bundle = list->data;
		list = list->next;
		if (!bundle) {
			continue;
		}
		bfiles = list_clone(bundle->files);
		files = list_concat(bfiles, files);
	}

	return files;
}
Example #28
0
/*
 * pull_ands
 *	  Recursively flatten nested AND clauses into a single and-clause list.
 *
 * Input is the arglist of an AND clause.
 * Returns the rebuilt arglist (note original list structure is not touched).
 */
static List *
pull_ands(List *andlist)
{
	List	   *out_list = NIL;
	ListCell   *arg;

	foreach(arg, andlist)
	{
		Node	   *subexpr = (Node *) lfirst(arg);

		/*
		 * Note: we can destructively concat the subexpression's arglist
		 * because we know the recursive invocation of pull_ands will have
		 * built a new arglist not shared with any other expr. Otherwise we'd
		 * need a list_copy here.
		 */
		if (and_clause(subexpr))
			out_list = list_concat(out_list,
								   pull_ands(((BoolExpr *) subexpr)->args));
		else
			out_list = lappend(out_list, subexpr);
	}
Example #29
0
static const char *
sonar_get_option(const char *optname, Oid tbl)
{
    ForeignTable *foreignTable = NULL;
    List *optionList = NIL;
    ListCell *optionCell = NULL;
    const char *val = NULL;

    foreignTable = GetForeignTable(tbl);

    optionList = list_concat(optionList, foreignTable->options);

    foreach(optionCell, optionList)
    {
        DefElem *optionDef = (DefElem *) lfirst(optionCell);
        char *optionDefName = optionDef->defname;

        if (strncmp(optionDefName, optname, NAMEDATALEN) == 0)
        {
            val = defGetString(optionDef);
            break;
        }
    }
Example #30
0
/*
 * Get any row security quals and check quals that should be applied to the
 * specified RTE.
 *
 * In addition, hasRowSecurity is set to true if row level security is enabled
 * (even if this RTE doesn't have any row security quals), and hasSubLinks is
 * set to true if any of the quals returned contain sublinks.
 */
void
get_row_security_policies(Query *root, CmdType commandType, RangeTblEntry *rte,
						  int rt_index, List **securityQuals,
						  List **withCheckOptions, bool *hasRowSecurity,
						  bool *hasSubLinks)
{
	Expr	   *rowsec_expr = NULL;
	Expr	   *rowsec_with_check_expr = NULL;
	Expr	   *hook_expr_restrictive = NULL;
	Expr	   *hook_with_check_expr_restrictive = NULL;
	Expr	   *hook_expr_permissive = NULL;
	Expr	   *hook_with_check_expr_permissive = NULL;

	List	   *rowsec_policies;
	List	   *hook_policies_restrictive = NIL;
	List	   *hook_policies_permissive = NIL;

	Relation	rel;
	Oid			user_id;
	int			rls_status;
	bool		defaultDeny = false;

	/* Defaults for the return values */
	*securityQuals = NIL;
	*withCheckOptions = NIL;
	*hasRowSecurity = false;
	*hasSubLinks = false;

	/* If this is not a normal relation, just return immediately */
	if (rte->relkind != RELKIND_RELATION)
		return;

	/* Switch to checkAsUser if it's set */
	user_id = rte->checkAsUser ? rte->checkAsUser : GetUserId();

	/* Determine the state of RLS for this, pass checkAsUser explicitly */
	rls_status = check_enable_rls(rte->relid, rte->checkAsUser, false);

	/* If there is no RLS on this table at all, nothing to do */
	if (rls_status == RLS_NONE)
		return;

	/*
	 * RLS_NONE_ENV means we are not doing any RLS now, but that may change
	 * with changes to the environment, so we mark it as hasRowSecurity to
	 * force a re-plan when the environment changes.
	 */
	if (rls_status == RLS_NONE_ENV)
	{
		/*
		 * Indicate that this query may involve RLS and must therefore be
		 * replanned if the environment changes (GUCs, role), but we are not
		 * adding anything here.
		 */
		*hasRowSecurity = true;

		return;
	}

	/* Grab the built-in policies which should be applied to this relation. */
	rel = heap_open(rte->relid, NoLock);

	rowsec_policies = pull_row_security_policies(commandType, rel,
												 user_id);

	/*
	 * Check if this is only the default-deny policy.
	 *
	 * Normally, if the table has row security enabled but there are no
	 * policies, we use a default-deny policy and not allow anything. However,
	 * when an extension uses the hook to add their own policies, we don't
	 * want to include the default deny policy or there won't be any way for a
	 * user to use an extension exclusively for the policies to be used.
	 */
	if (((RowSecurityPolicy *) linitial(rowsec_policies))->policy_id
		== InvalidOid)
		defaultDeny = true;

	/* Now that we have our policies, build the expressions from them. */
	process_policies(root, rowsec_policies, rt_index, &rowsec_expr,
					 &rowsec_with_check_expr, hasSubLinks, OR_EXPR);

	/*
	 * Also, allow extensions to add their own policies.
	 *
	 * extensions can add either permissive or restrictive policies.
	 *
	 * Note that, as with the internal policies, if multiple policies are
	 * returned then they will be combined into a single expression with all
	 * of them OR'd (for permissive) or AND'd (for restrictive) together.
	 *
	 * If only a USING policy is returned by the extension then it will be
	 * used for WITH CHECK as well, similar to how internal policies are
	 * handled.
	 *
	 * The only caveat to this is that if there are NO internal policies
	 * defined, there ARE policies returned by the extension, and RLS is
	 * enabled on the table, then we will ignore the internally-generated
	 * default-deny policy and use only the policies returned by the
	 * extension.
	 */
	if (row_security_policy_hook_restrictive)
	{
		hook_policies_restrictive = (*row_security_policy_hook_restrictive) (commandType, rel);

		/* Build the expression from any policies returned. */
		if (hook_policies_restrictive != NIL)
			process_policies(root, hook_policies_restrictive, rt_index,
							 &hook_expr_restrictive,
							 &hook_with_check_expr_restrictive,
							 hasSubLinks,
							 AND_EXPR);
	}

	if (row_security_policy_hook_permissive)
	{
		hook_policies_permissive = (*row_security_policy_hook_permissive) (commandType, rel);

		/* Build the expression from any policies returned. */
		if (hook_policies_permissive != NIL)
			process_policies(root, hook_policies_permissive, rt_index,
							 &hook_expr_permissive,
							 &hook_with_check_expr_permissive, hasSubLinks,
							 OR_EXPR);
	}

	/*
	 * If the only built-in policy is the default-deny one, and hook policies
	 * exist, then use the hook policies only and do not apply the
	 * default-deny policy.  Otherwise, we will apply both sets below.
	 */
	if (defaultDeny &&
		(hook_policies_restrictive != NIL || hook_policies_permissive != NIL))
	{
		rowsec_expr = NULL;
		rowsec_with_check_expr = NULL;
	}

	/*
	 * For INSERT or UPDATE, we need to add the WITH CHECK quals to Query's
	 * withCheckOptions to verify that any new records pass the WITH CHECK
	 * policy (this will be a copy of the USING policy, if no explicit WITH
	 * CHECK policy exists).
	 */
	if (commandType == CMD_INSERT || commandType == CMD_UPDATE)
	{
		/*
		 * WITH CHECK OPTIONS wants a WCO node which wraps each Expr, so
		 * create them as necessary.
		 */

		/*
		 * Handle any restrictive policies first.
		 *
		 * They can simply be added.
		 */
		if (hook_with_check_expr_restrictive)
		{
			WithCheckOption *wco;

			wco = (WithCheckOption *) makeNode(WithCheckOption);
			wco->kind = commandType == CMD_INSERT ? WCO_RLS_INSERT_CHECK :
				WCO_RLS_UPDATE_CHECK;
			wco->relname = pstrdup(RelationGetRelationName(rel));
			wco->qual = (Node *) hook_with_check_expr_restrictive;
			wco->cascaded = false;
			*withCheckOptions = lappend(*withCheckOptions, wco);
		}

		/*
		 * Handle built-in policies, if there are no permissive policies from
		 * the hook.
		 */
		if (rowsec_with_check_expr && !hook_with_check_expr_permissive)
		{
			WithCheckOption *wco;

			wco = (WithCheckOption *) makeNode(WithCheckOption);
			wco->kind = commandType == CMD_INSERT ? WCO_RLS_INSERT_CHECK :
				WCO_RLS_UPDATE_CHECK;
			wco->relname = pstrdup(RelationGetRelationName(rel));
			wco->qual = (Node *) rowsec_with_check_expr;
			wco->cascaded = false;
			*withCheckOptions = lappend(*withCheckOptions, wco);
		}
		/* Handle the hook policies, if there are no built-in ones. */
		else if (!rowsec_with_check_expr && hook_with_check_expr_permissive)
		{
			WithCheckOption *wco;

			wco = (WithCheckOption *) makeNode(WithCheckOption);
			wco->kind = commandType == CMD_INSERT ? WCO_RLS_INSERT_CHECK :
				WCO_RLS_UPDATE_CHECK;
			wco->relname = pstrdup(RelationGetRelationName(rel));
			wco->qual = (Node *) hook_with_check_expr_permissive;
			wco->cascaded = false;
			*withCheckOptions = lappend(*withCheckOptions, wco);
		}
		/* Handle the case where there are both. */
		else if (rowsec_with_check_expr && hook_with_check_expr_permissive)
		{
			WithCheckOption *wco;
			List	   *combined_quals = NIL;
			Expr	   *combined_qual_eval;

			combined_quals = lcons(copyObject(rowsec_with_check_expr),
								   combined_quals);

			combined_quals = lcons(copyObject(hook_with_check_expr_permissive),
								   combined_quals);

			combined_qual_eval = makeBoolExpr(OR_EXPR, combined_quals, -1);

			wco = (WithCheckOption *) makeNode(WithCheckOption);
			wco->kind = commandType == CMD_INSERT ? WCO_RLS_INSERT_CHECK :
				WCO_RLS_UPDATE_CHECK;
			wco->relname = pstrdup(RelationGetRelationName(rel));
			wco->qual = (Node *) combined_qual_eval;
			wco->cascaded = false;
			*withCheckOptions = lappend(*withCheckOptions, wco);
		}

		/*
		 * ON CONFLICT DO UPDATE has an RTE that is subject to both INSERT and
		 * UPDATE RLS enforcement.  Those are enforced (as a special, distinct
		 * kind of WCO) on the target tuple.
		 *
		 * Make a second, recursive pass over the RTE for this, gathering
		 * UPDATE-applicable RLS checks/WCOs, and gathering and converting
		 * UPDATE-applicable security quals into WCO_RLS_CONFLICT_CHECK RLS
		 * checks/WCOs.  Finally, these distinct kinds of RLS checks/WCOs are
		 * concatenated with our own INSERT-applicable list.
		 */
		if (root->onConflict && root->onConflict->action == ONCONFLICT_UPDATE &&
			commandType == CMD_INSERT)
		{
			List	   *conflictSecurityQuals = NIL;
			List	   *conflictWCOs = NIL;
			ListCell   *item;
			bool		conflictHasRowSecurity = false;
			bool		conflictHasSublinks = false;

			/* Assume that RTE is target resultRelation */
			get_row_security_policies(root, CMD_UPDATE, rte, rt_index,
									  &conflictSecurityQuals, &conflictWCOs,
									  &conflictHasRowSecurity,
									  &conflictHasSublinks);

			if (conflictHasRowSecurity)
				*hasRowSecurity = true;
			if (conflictHasSublinks)
				*hasSubLinks = true;

			/*
			 * Append WITH CHECK OPTIONs/RLS checks, which should not conflict
			 * between this INSERT and the auxiliary UPDATE
			 */
			*withCheckOptions = list_concat(*withCheckOptions,
											conflictWCOs);

			foreach(item, conflictSecurityQuals)
			{
				Expr	   *conflict_rowsec_expr = (Expr *) lfirst(item);
				WithCheckOption *wco;

				wco = (WithCheckOption *) makeNode(WithCheckOption);

				wco->kind = WCO_RLS_CONFLICT_CHECK;
				wco->relname = pstrdup(RelationGetRelationName(rel));
				wco->qual = (Node *) copyObject(conflict_rowsec_expr);
				wco->cascaded = false;
				*withCheckOptions = lappend(*withCheckOptions, wco);
			}
		}