Esempio n. 1
0
/*
 * Process any command-line switches and any additional GUC variable
 * settings passed in the startup packet.
 */
static void
process_startup_options(Port *port, bool am_superuser)
{
    GucContext	gucctx;
    ListCell   *gucopts;

    gucctx = am_superuser ? PGC_SUSET : PGC_BACKEND;

    /*
     * First process any command-line switches that were included in the
     * startup packet, if we are in a regular backend.
     */
    if (port->cmdline_options != NULL)
    {
        /*
         * The maximum possible number of commandline arguments that could
         * come from port->cmdline_options is (strlen + 1) / 2; see
         * pg_split_opts().
         */
        char	  **av;
        int			maxac;
        int			ac;

        maxac = 2 + (strlen(port->cmdline_options) + 1) / 2;

        av = (char **) palloc(maxac * sizeof(char *));
        ac = 0;

        av[ac++] = "postgres";

        /* Note this mangles port->cmdline_options */
        pg_split_opts(av, &ac, port->cmdline_options);

        av[ac] = NULL;

        Assert(ac < maxac);

        (void) process_postgres_switches(ac, av, gucctx, NULL);
    }

    /*
     * Process any additional GUC variable settings passed in startup packet.
     * These are handled exactly like command-line variables.
     */
    gucopts = list_head(port->guc_options);
    while (gucopts)
    {
        char	   *name;
        char	   *value;

        name = lfirst(gucopts);
        gucopts = lnext(gucopts);

        value = lfirst(gucopts);
        gucopts = lnext(gucopts);

        SetConfigOption(name, value, gucctx, PGC_S_CLIENT);
    }
}
Esempio n. 2
0
/*
 * SendRowDescriptionMessage --- send a RowDescription message to the frontend
 *
 * Notes: the TupleDesc has typically been manufactured by ExecTypeFromTL()
 * or some similar function; it does not contain a full set of fields.
 * The targetlist will be NIL when executing a utility function that does
 * not have a plan.  If the targetlist isn't NIL then it is a Query node's
 * targetlist; it is up to us to ignore resjunk columns in it.  The formats[]
 * array pointer might be NULL (if we are doing Describe on a prepared stmt);
 * send zeroes for the format codes in that case.
 */
void
SendRowDescriptionMessage(TupleDesc typeinfo, List *targetlist, int16 *formats)
{
	Form_pg_attribute *attrs = typeinfo->attrs;
	int			natts = typeinfo->natts;
	int			proto = PG_PROTOCOL_MAJOR(FrontendProtocol);
	int			i;
	StringInfoData buf;
	ListCell   *tlist_item = list_head(targetlist);

	pq_beginmessage(&buf, 'T'); /* tuple descriptor message type */
	pq_sendint(&buf, natts, 2); /* # of attrs in tuples */

	for (i = 0; i < natts; ++i)
	{
		Oid			atttypid = attrs[i]->atttypid;
		int32		atttypmod = attrs[i]->atttypmod;

		pq_sendstring(&buf, NameStr(attrs[i]->attname));
		/* column ID info appears in protocol 3.0 and up */
		if (proto >= 3)
		{
			/* Do we have a non-resjunk tlist item? */
			while (tlist_item &&
				   ((TargetEntry *) lfirst(tlist_item))->resjunk)
				tlist_item = lnext(tlist_item);
			if (tlist_item)
			{
				TargetEntry *tle = (TargetEntry *) lfirst(tlist_item);

				pq_sendint(&buf, tle->resorigtbl, 4);
				pq_sendint(&buf, tle->resorigcol, 2);
				tlist_item = lnext(tlist_item);
			}
			else
			{
				/* No info available, so send zeroes */
				pq_sendint(&buf, 0, 4);
				pq_sendint(&buf, 0, 2);
			}
		}
		/* If column is a domain, send the base type and typmod instead */
		atttypid = getBaseTypeAndTypmod(atttypid, &atttypmod);
		pq_sendint(&buf, (int) atttypid, sizeof(atttypid));
		pq_sendint(&buf, attrs[i]->attlen, sizeof(attrs[i]->attlen));
		/* typmod appears in protocol 2.0 and up */
		if (proto >= 2)
			pq_sendint(&buf, atttypmod, sizeof(atttypmod));
		/* format info appears in protocol 3.0 and up */
		if (proto >= 3)
		{
			if (formats)
				pq_sendint(&buf, formats[i], 2);
			else
				pq_sendint(&buf, 0, 2);
		}
	}
	pq_endmessage(&buf);
}
Esempio n. 3
0
/*
 * Iterate over the list of programmers given as "programmers", and
 * call the callback function cb for each entry found.  cb is being
 * passed the following arguments:
 * . the name of the programmer (for -c)
 * . the descriptive text given in the config file
 * . the name of the config file this programmer has been defined in
 * . the line number of the config file this programmer has been defined at
 * . the "cookie" passed into walk_programmers() (opaque client data)
 */
void walk_programmers(LISTID programmers, walk_programmers_cb cb, void *cookie)
{
  LNODEID ln1;
  LNODEID ln2;
  PROGRAMMER * p;

  for (ln1 = lfirst(programmers); ln1; ln1 = lnext(ln1)) {
    p = ldata(ln1);
    for (ln2=lfirst(p->id); ln2; ln2=lnext(ln2)) {
      cb(ldata(ln2), p->desc, p->config_file, p->lineno, cookie);
    }
  }
}
Esempio n. 4
0
/*
 * Do a word motion with operator op, and cnt more words
 * to go after this.
 */
int 
word(register void (*op)(int), int cnt)
{
	register int which = 0, i;
	register char *iwc;
	register line *iwdot = wdot;

	if (dir == 1) {
		iwc = wcursor;
		which = wordch(wcursor);
		while (wordof(which, wcursor)) {
			if (cnt == 1 && op != vmove &&
					wcursor[i = skipright(linebuf, wcursor)]
					== 0) {
				wcursor += i;
				break;
			}
			if (!lnext())
				return (0);
			if (wcursor == linebuf)
				break;
		}
		/* Unless last segment of a change skip blanks */
		if (op != vchange || cnt > 1)
			while (!margin() && blank())
				wcursor += skipright(linebuf, wcursor);
		else
			if (wcursor == iwc && iwdot == wdot && *iwc)
				wcursor += skipright(linebuf, wcursor);
		if (op == vmove && margin()) {
			if (wcursor == linebuf)
				wcursor--;
			else if (!lnext())
				return (0);
		}
	} else {
		if (!lnext())
			return (0);
		while (blank())
			if (!lnext())
				return (0);
		if (!margin()) {
			which = wordch(wcursor);
			while (!margin() && wordof(which, wcursor))
				wcursor--;
		}
		if (wcursor < linebuf || !wordof(which, wcursor))
			wcursor += skipright(linebuf, wcursor);
	}
	return (1);
}
Esempio n. 5
0
/*
 * Delete 'cell' from 'list'; 'prev' is the previous element to 'cell'
 * in 'list', if any (i.e. prev == NULL iff list->head == cell)
 *
 * The cell is pfree'd, as is the List header if this was the last member.
 */
List *
list_delete_cell(List *list, ListCell *cell, ListCell *prev)
{
	check_list_invariants(list);
	Assert(prev != NULL ? lnext(prev) == cell : list_head(list) == cell);

	/*
	 * If we're about to delete the last node from the list, free the whole
	 * list instead and return NIL, which is the only valid representation of
	 * a zero-length list.
	 */
	if (list->length == 1)
	{
		list_free(list);
		return NIL;
	}

	/*
	 * Otherwise, adjust the necessary list links, deallocate the particular
	 * node we have just removed, and return the list we were given.
	 */
	list->length--;

	if (prev)
		prev->next = cell->next;
	else
		list->head = cell->next;

	if (list->tail == cell)
		list->tail = prev;

	pfree(cell);
	return list;
}
Esempio n. 6
0
File: kmail.c Progetto: klopp/ksmtp
static int mail_AttachFiles( KMail mail, KMsg msg, const char * boundary )
{
    struct _MFile file =
    { NULL, NULL };
    Pair afile = lfirst( msg->afiles );
    file.headers = snew();

    while( afile )
    {
        if( !msg_CreateFile( msg, &file, mail->error, boundary, F_NAME(afile),
                F_CTYPE(afile), "attachment", NULL ) )
        {
            return delMFile( &file );
        }
        if( !smtp_write( mail->smtp, sstr( file.headers ) )
                || !smtp_write( mail->smtp, sstr( file.body ) )
                || !smtp_write( mail->smtp, "\r\n" ) )
        {
            mail_FormatError( mail, "mail_AttachFiles(\"%s\"), internal error",
                    F_NAME(afile) );
            return delMFile( &file );
        }
        afile = lnext( msg->afiles );
    }
    delMFile( &file );
    return 1;
}
Esempio n. 7
0
/*
 * listCopy--
 *    this copy function only copies the "lcons-cells" of the list but not
 *    its contents. (good for list of pointers as well as list of integers).
 */
List *
listCopy(List *list)
{
    List *newlist=NIL;
    List *l, *nl;

    foreach(l, list) {
	if (newlist==NIL) {
	    newlist = nl = lcons(lfirst(l),NIL);
	}else {
	    lnext(nl) = lcons(lfirst(l),NIL);
	    nl = lnext(nl);
	}
    }
    return newlist; 
}
Esempio n. 8
0
/*
 * set_cheapest
 *	  Find the minimum-cost paths from among a relation's paths,
 *	  and save them in the rel's cheapest-path fields.
 *
 * This is normally called only after we've finished constructing the path
 * list for the rel node.
 *
 * If we find two paths of identical costs, try to keep the better-sorted one.
 * The paths might have unrelated sort orderings, in which case we can only
 * guess which might be better to keep, but if one is superior then we
 * definitely should keep it.
 */
void
set_cheapest(rel_optmz_info_n *parent_rel)
{
	struct list* pathlist = parent_rel->pathlist;
	struct list_cell* p;
	path_n* cheapest_startup_path;
	path_n* cheapest_total_path;

	ASSERT(IS_A(parent_rel, RelOptInfo));

	if (pathlist == NIL)
		elog(ERROR, "could not devise a query plan for the given query");

	cheapest_startup_path = cheapest_total_path = (path_n *) linitial(pathlist);

	for_each_cell(p, lnext(list_head(pathlist))) {
		path_n* path = (path_n *) lfirst(p);
		int cmp;

		cmp = cmp_path_costs(cheapest_startup_path, path, STARTUP_COST);
		if (cmp > 0
			|| (cmp == 0
				&& cmp_pathkeys(cheapest_startup_path->pathkeys,
					path->pathkeys) == PATHKEYS_BETTER2))
			cheapest_startup_path = path;

		cmp = cmp_path_costs(cheapest_total_path, path, TOTAL_COST);
		if (cmp > 0 ||
			(cmp == 0 &&
				cmp_pathkeys(cheapest_total_path->pathkeys,
					path->pathkeys) == PATHKEYS_BETTER2))
			cheapest_total_path = path;
	}
Esempio n. 9
0
File: kheader.c Progetto: klopp/knet
static int hdr_MakeTextHeaders( msg_Headers headers, const char * charset,
        string out )
{
    msg_Header header;
    char cprefix[32];
    string rc = snew();
    if( !rc ) return 0;

    if( !isUsAsciiCs( charset ) ) snprintf( cprefix, sizeof(cprefix) - 1,
            "=?%s?B?", charset );
    else *cprefix = 0;

    header = lfirst( headers->text );
    while( header )
    {
        if( !hdr_MakeTextHeader( header, cprefix, rc ) )
        {
            sdel( rc );
            return 0;
        }
        header = lnext( headers->text );
    }
    if( !scat( out, rc ) )
    {
        sdel( rc );
        return 0;
    }
    sdel( rc );
    return 1;
}
Esempio n. 10
0
/*
 * sepgsql_subxact_callback
 *
 * A callback routine of sub-transaction start/abort/commit.  Releases all
 * security labels that are set within the sub-transaction that is aborted.
 */
static void
sepgsql_subxact_callback(SubXactEvent event, SubTransactionId mySubid,
						 SubTransactionId parentSubid, void *arg)
{
	ListCell   *cell;
	ListCell   *prev;
	ListCell   *next;

	if (event == SUBXACT_EVENT_ABORT_SUB)
	{
		prev = NULL;
		for (cell = list_head(client_label_pending); cell; cell = next)
		{
			pending_label *plabel = lfirst(cell);

			next = lnext(cell);

			if (plabel->subid == mySubid)
				client_label_pending
					= list_delete_cell(client_label_pending, cell, prev);
			else
				prev = cell;
		}
	}
}
Esempio n. 11
0
File: kmail.c Progetto: klopp/ksmtp
static int mail_EmbedFiles( KMail mail, KMsg msg, const char * boundary )
{
    struct _MFile file =
    { NULL, NULL };
    EFile efile = lfirst( msg->efiles );
    file.headers = snew();

    while( efile )
    {
        if( !msg_CreateFile( msg, &file, mail->error, boundary, efile->name,
                efile->ctype, "inline", efile->cid ) )
        {
            return delMFile( &file );
        }
        if( !smtp_write( mail->smtp, sstr( file.headers ) )
                || !smtp_write( mail->smtp, sstr( file.body ) )
                || !smtp_write( mail->smtp, "\r\n" ) )
        {
            mail_FormatError( mail, "mail_EmbedFiles(\"%s\"), internal error",
                    efile->name );
            return delMFile( &file );
        }
        efile = lnext( msg->efiles );
    }
    delMFile( &file );
    return 1;
}
/*
 * set_cheapest
 *	  Find the minimum-cost paths from among a relation's paths,
 *	  and save them in the rel's cheapest-path fields.
 *
 * This is normally called only after we've finished constructing the path
 * list for the rel node.
 *
 * If we find two paths of identical costs, try to keep the better-sorted one.
 * The paths might have unrelated sort orderings, in which case we can only
 * guess which might be better to keep, but if one is superior then we
 * definitely should keep it.
 */
void
set_cheapest(RelOptInfo *parent_rel)
{
	List	   *pathlist = parent_rel->pathlist;
	ListCell   *p;
	Path	   *cheapest_startup_path;
	Path	   *cheapest_total_path;

	Assert(IsA(parent_rel, RelOptInfo));

	if (pathlist == NIL)
		elog(ERROR, "could not devise a query plan for the given query");

	cheapest_startup_path = cheapest_total_path = (Path *) linitial(pathlist);

	for_each_cell(p, lnext(list_head(pathlist)))
	{
		Path	   *path = (Path *) lfirst(p);
		int			cmp;

		cmp = compare_path_costs(cheapest_startup_path, path, STARTUP_COST);
		if (cmp > 0 ||
			(cmp == 0 &&
			 compare_pathkeys(cheapest_startup_path->pathkeys,
							  path->pathkeys) == PATHKEYS_BETTER2))
			cheapest_startup_path = path;

		cmp = compare_path_costs(cheapest_total_path, path, TOTAL_COST);
		if (cmp > 0 ||
			(cmp == 0 &&
			 compare_pathkeys(cheapest_total_path->pathkeys,
							  path->pathkeys) == PATHKEYS_BETTER2))
			cheapest_total_path = path;
	}
Esempio n. 13
0
static int wiring_parseextparms(PROGRAMMER * pgm, LISTID extparms)
{
  LNODEID ln;
  const char *extended_param;
  int rv = 0;
  void *mycookie = STK500V2PDATA(pgm)->chained_pdata;

  for (ln = lfirst(extparms); ln; ln = lnext(ln)) {
    extended_param = ldata(ln);

    if (strncmp(extended_param, "snooze=", strlen("snooze=")) == 0) {
      int newsnooze;
      if (sscanf(extended_param, "snooze=%i", &newsnooze) != 1 ||
          newsnooze < 0) {
        avrdude_message(MSG_INFO, "%s: wiring_parseextparms(): invalid snooze time '%s'\n",
                        progname, extended_param);
        rv = -1;
        continue;
      }
      avrdude_message(MSG_NOTICE2, "%s: wiring_parseextparms(): snooze time set to %d ms\n",
                      progname, newsnooze);
      WIRINGPDATA(mycookie)->snoozetime = newsnooze;

      continue;
    }

    avrdude_message(MSG_INFO, "%s: wiring_parseextparms(): invalid extended parameter '%s'\n",
                    progname, extended_param);
    rv = -1;
  }

  return rv;
}
EdgePointer CDelaunay::connectLeft(EdgePointer a, EdgePointer b)
{
  EdgePointer ans;
  ans = makeEdge(dest(a), orig(b));
  splice(ans, (EdgePointer) lnext(a));
  splice((EdgePointer) sym(ans), b);
  return(ans);
}
Esempio n. 15
0
/*
 * master_get_table_ddl_events takes in a relation name, and returns the set of
 * DDL commands needed to reconstruct the relation. The returned DDL commands
 * are similar in flavor to schema definitions that pgdump returns. The function
 * errors if given relation does not exist.
 */
Datum
master_get_table_ddl_events(PG_FUNCTION_ARGS)
{
	FuncCallContext *functionContext = NULL;
	ListCell *tableDDLEventCell = NULL;

	/*
	 * On the very first call to this function, we first use the given relation
	 * name to get to the relation. We then recreate the list of DDL statements
	 * issued for this relation, and save the first statement's position in the
	 * function context.
	 */
	if (SRF_IS_FIRSTCALL())
	{
		text *relationName = PG_GETARG_TEXT_P(0);
		Oid relationId = ResolveRelationId(relationName);

		MemoryContext oldContext = NULL;
		List *tableDDLEventList = NIL;

		/* create a function context for cross-call persistence */
		functionContext = SRF_FIRSTCALL_INIT();

		/* switch to memory context appropriate for multiple function calls */
		oldContext = MemoryContextSwitchTo(functionContext->multi_call_memory_ctx);

		/* allocate DDL statements, and then save position in DDL statements */
		tableDDLEventList = GetTableDDLEvents(relationId);
		tableDDLEventCell = list_head(tableDDLEventList);

		functionContext->user_fctx = tableDDLEventCell;

		MemoryContextSwitchTo(oldContext);
	}

	/*
	 * On every call to this function, we get the current position in the
	 * statement list. We then iterate to the next position in the list and
	 * return the current statement, if we have not yet reached the end of
	 * list.
	 */
	functionContext = SRF_PERCALL_SETUP();

	tableDDLEventCell = (ListCell *) functionContext->user_fctx;
	if (tableDDLEventCell != NULL)
	{
		char *ddlStatement = (char *) lfirst(tableDDLEventCell);
		text *ddlStatementText = cstring_to_text(ddlStatement);

		functionContext->user_fctx = lnext(tableDDLEventCell);

		SRF_RETURN_NEXT(functionContext, PointerGetDatum(ddlStatementText));
	}
	else
	{
		SRF_RETURN_DONE(functionContext);
	}
}
Esempio n. 16
0
static bool
tlist_matches_tupdesc(PlanState *ps, List *tlist, Index varno, TupleDesc tupdesc)
{
	int			numattrs = tupdesc->natts;
	int			attrno;
	bool		hasoid;
	ListCell   *tlist_item = list_head(tlist);

	/* Check the tlist attributes */
	for (attrno = 1; attrno <= numattrs; attrno++)
	{
		Form_pg_attribute att_tup = tupdesc->attrs[attrno - 1];
		Var		   *var;

		if (tlist_item == NULL)
			return false;		/* tlist too short */
		var = (Var *) ((TargetEntry *) lfirst(tlist_item))->expr;
		if (!var || !IsA(var, Var))
			return false;		/* tlist item not a Var */
		/* if these Asserts fail, planner messed up */
		Assert(var->varno == varno);
		Assert(var->varlevelsup == 0);
		if (var->varattno != attrno)
			return false;		/* out of order */
		if (att_tup->attisdropped)
			return false;		/* table contains dropped columns */

		/*
		 * Note: usually the Var's type should match the tupdesc exactly, but
		 * in situations involving unions of columns that have different
		 * typmods, the Var may have come from above the union and hence have
		 * typmod -1.  This is a legitimate situation since the Var still
		 * describes the column, just not as exactly as the tupdesc does. We
		 * could change the planner to prevent it, but it'd then insert
		 * projection steps just to convert from specific typmod to typmod -1,
		 * which is pretty silly.
		 */
		if (var->vartype != att_tup->atttypid ||
			(var->vartypmod != att_tup->atttypmod &&
			 var->vartypmod != -1))
			return false;		/* type mismatch */

		tlist_item = lnext(tlist_item);
	}

	if (tlist_item)
		return false;			/* tlist too long */

	/*
	 * If the plan context requires a particular hasoid setting, then that has
	 * to match, too.
	 */
	if (ExecContextForcesOids(ps, &hasoid) &&
		hasoid != tupdesc->tdhasoid)
		return false;

	return true;
}
Esempio n. 17
0
/* Copied from src/backend/optimizer/util/plancat.c, not exported.
 *
 * Build a targetlist representing the columns of the specified index.
 * Each column is represented by a Var for the corresponding base-relation
 * column, or an expression in base-relation Vars, as appropriate.
 *
 * There are never any dropped columns in indexes, so unlike
 * build_physical_tlist, we need no failure case.
 */
List *
build_index_tlist(PlannerInfo *root, IndexOptInfo *index,
				  Relation heapRelation)
{
	List	   *tlist = NIL;
	Index		varno = index->rel->relid;
	ListCell   *indexpr_item;
	int			i;

	indexpr_item = list_head(index->indexprs);
	for (i = 0; i < index->ncolumns; i++)
	{
		int			indexkey = index->indexkeys[i];
		Expr	   *indexvar;

		if (indexkey != 0)
		{
			/* simple column */
			Form_pg_attribute att_tup;

			if (indexkey < 0)
				att_tup = SystemAttributeDefinition(indexkey,
										   heapRelation->rd_rel->relhasoids);
			else
#if PG_VERSION_NUM >= 110000
				att_tup = TupleDescAttr(heapRelation->rd_att, indexkey - 1);
#else
				att_tup = heapRelation->rd_att->attrs[indexkey - 1];
#endif

			indexvar = (Expr *) makeVar(varno,
										indexkey,
										att_tup->atttypid,
										att_tup->atttypmod,
										att_tup->attcollation,
										0);
		}
		else
		{
			/* expression column */
			if (indexpr_item == NULL)
				elog(ERROR, "wrong number of index expressions");
			indexvar = (Expr *) lfirst(indexpr_item);
			indexpr_item = lnext(indexpr_item);
		}

		tlist = lappend(tlist,
						makeTargetEntry(indexvar,
										i + 1,
										NULL,
										false));
	}
	if (indexpr_item != NULL)
		elog(ERROR, "wrong number of index expressions");

	return tlist;
}
Esempio n. 18
0
int
ltosol1(register char *parens)
{
	register char *cp;

	if (*parens && !*wcursor && !lnext())
		return (0);
	while (isspace(*wcursor&0377) || (*wcursor == 0 && *parens))
		if (!lnext())
			return (0);
	if (any(*wcursor, parens) || dir > 0)
		return (1);
	for (cp = wcursor; cp > linebuf; cp--)
		if (isspace(cp[-1]&0377) || any(cp[-1], parens))
			break;
	wcursor = cp;
	return (1);
}
Esempio n. 19
0
/* ----------------
 *		FormIndexDatum
 *			Construct Datum[] and nullv[] arrays for a new index tuple.
 *
 *	indexInfo		Info about the index
 *	heapTuple		Heap tuple for which we must prepare an index entry
 *	heapDescriptor	tupledesc for heap tuple
 *	estate			executor state for evaluating any index expressions
 *	datum			Array of index Datums (output area)
 *	nullv			Array of is-null indicators (output area)
 *
 * When there are no index expressions, estate may be NULL.  Otherwise it
 * must be supplied, *and* the ecxt_scantuple slot of its per-tuple expr
 * context must point to the heap tuple passed in.
 *
 * For largely historical reasons, we don't actually call index_formtuple()
 * here, we just prepare its input arrays datum[] and nullv[].
 * ----------------
 */
void
FormIndexDatum(IndexInfo *indexInfo,
			   HeapTuple heapTuple,
			   TupleDesc heapDescriptor,
			   EState *estate,
			   Datum *datum,
			   char *nullv)
{
	List	   *indexprs;
	int			i;

	if (indexInfo->ii_Expressions != NIL &&
		indexInfo->ii_ExpressionsState == NIL)
	{
		/* First time through, set up expression evaluation state */
		indexInfo->ii_ExpressionsState = (List *)
			ExecPrepareExpr((Expr *) indexInfo->ii_Expressions,
							estate);
		/* Check caller has set up context correctly */
		Assert(GetPerTupleExprContext(estate)->ecxt_scantuple->val == heapTuple);
	}
	indexprs = indexInfo->ii_ExpressionsState;

	for (i = 0; i < indexInfo->ii_NumIndexAttrs; i++)
	{
		int			keycol = indexInfo->ii_KeyAttrNumbers[i];
		Datum		iDatum;
		bool		isNull;

		if (keycol != 0)
		{
			/*
			 * Plain index column; get the value we need directly from the
			 * heap tuple.
			 */
			iDatum = heap_getattr(heapTuple, keycol, heapDescriptor, &isNull);
		}
		else
		{
			/*
			 * Index expression --- need to evaluate it.
			 */
			if (indexprs == NIL)
				elog(ERROR, "wrong number of index expressions");
			iDatum = ExecEvalExprSwitchContext((ExprState *) lfirst(indexprs),
										  GetPerTupleExprContext(estate),
											   &isNull,
											   NULL);
			indexprs = lnext(indexprs);
		}
		datum[i] = iDatum;
		nullv[i] = (isNull) ? 'n' : ' ';
	}

	if (indexprs != NIL)
		elog(ERROR, "wrong number of index expressions");
}
/*
 * gp_partition_expansion
 *   Find all child partition oids for the given parent oid.
 *
 * This function is a set-returning function, returning a set of
 * child oids.
 */
Datum
gp_partition_expansion(PG_FUNCTION_ARGS)
{
	FuncCallContext *funcCallContext = NULL;
	
	/*
	 * Setup the function call context for set-returning functions.
	 * At the first time of calling this function, we find the partition
	 * metadata for the given parent oid, and store that in an PartitionIterator
	 * structure.
	 */
	if (SRF_IS_FIRSTCALL())
	{
		funcCallContext = SRF_FIRSTCALL_INIT();

		Oid parentOid = PG_GETARG_OID(0);

		MemoryContext oldContext = MemoryContextSwitchTo(funcCallContext->multi_call_memory_ctx);

		funcCallContext->user_fctx = createPartitionIterator(parentOid);

		MemoryContextSwitchTo(oldContext);
	}
	funcCallContext = SRF_PERCALL_SETUP();

	PartitionIterator *partitionIterator = (PartitionIterator *)funcCallContext->user_fctx;
	Assert(partitionIterator != NULL);
	ListCell *ruleCell = partitionIterator->nextRuleCell;

	if (ruleCell != NULL)
	{
		partitionIterator->nextRuleCell = lnext(ruleCell);

		partitionIterator->currentRule = (PartitionRule *)lfirst(ruleCell);
		Oid childOid = partitionIterator->currentRule->parchildrelid;
		
		SRF_RETURN_NEXT(funcCallContext, ObjectIdGetDatum(childOid));
	}

	/*
	 * Return default partition oid if any.
	 */
	if (!partitionIterator->defaultPartReturned)
	{
		Assert(NULL != partitionIterator->partsAndRules);
		Assert(NULL != partitionIterator->partsAndRules->default_part);
		PartitionRule *defaultPart = partitionIterator->partsAndRules->default_part;
		Oid childOid = defaultPart->parchildrelid;
		partitionIterator->defaultPartReturned = true;

		SRF_RETURN_NEXT(funcCallContext, ObjectIdGetDatum(childOid));
	}

	pfree(partitionIterator);
	
	SRF_RETURN_DONE(funcCallContext);
}
Esempio n. 21
0
static int  pickit2_parseextparams(struct programmer_t * pgm, LISTID extparms)
{
    LNODEID ln;
    const char *extended_param;
    int rv = 0;

    for (ln = lfirst(extparms); ln; ln = lnext(ln))
    {
        extended_param = ldata(ln);

        if (strncmp(extended_param, "clockrate=", strlen("clockrate=")) == 0)
        {
            int clock_rate;
            if (sscanf(extended_param, "clockrate=%i", &clock_rate) != 1 || clock_rate <= 0)
            {
                avrdude_message(MSG_INFO, "%s: pickit2_parseextparms(): invalid clockrate '%s'\n",
                                progname, extended_param);
                rv = -1;
                continue;
            }

            int clock_period = MIN(1000000 / clock_rate, 255);    // max period is 255
            clock_rate = (int)(1000000 / (clock_period + 5e-7));    // assume highest speed is 2MHz - should probably check this

            avrdude_message(MSG_NOTICE2, "%s: pickit2_parseextparms(): clockrate set to 0x%02x\n",
                                progname, clock_rate);
            PDATA(pgm)->clock_period = clock_period;

            continue;
        }

        if (strncmp(extended_param, "timeout=", strlen("timeout=")) == 0)
        {
            int timeout;
            if (sscanf(extended_param, "timeout=%i", &timeout) != 1 || timeout <= 0)
            {
                avrdude_message(MSG_INFO, "%s: pickit2_parseextparms(): invalid timeout '%s'\n",
                                progname, extended_param);
                rv = -1;
                continue;
            }

            avrdude_message(MSG_NOTICE2, "%s: pickit2_parseextparms(): usb timeout set to 0x%02x\n",
                                progname, timeout);
            PDATA(pgm)->transaction_timeout = timeout;

            continue;
        }

        avrdude_message(MSG_INFO, "%s: pickit2_parseextparms(): invalid extended parameter '%s'\n",
                        progname, extended_param);
        rv = -1;
    }

    return rv;
}
Esempio n. 22
0
int
lindent(line *addr)
{
	register int i;
	char *swcurs = wcursor;
	line *swdot = wdot;

again:
	if (addr > one) {
		register char *cp;
		register int cnt = 0;

		addr--;
		getline(*addr);
		for (cp = linebuf; *cp; cp++)
			if (*cp == '(')
				cnt++;
			else if (*cp == ')')
				cnt--;
		cp = vpastwh(linebuf);
		if (*cp == 0)
			goto again;
		if (cnt == 0)
			return (whitecnt(linebuf));
		addr++;
	}
	wcursor = linebuf;
	linebuf[0] = 0;
	wdot = addr;
	dir = -1;
	llimit = one;
	lf = (void (*)(int))lindent;
	if (!lskipbal("()"))
		i = 0;
	else if (wcursor == linebuf)
		i = 2;
	else {
		register char *wp = wcursor;

		dir = 1;
		llimit = wdot;
		if (!lnext() || !ltosolid() || !lskipatom()) {
			wcursor = wp;
			i = 1;
		} else
			i = 0;
		i += column(wcursor) - 1;
		if (!inopen)
			i--;
	}
	wdot = swdot;
	wcursor = swcurs;
	return (i);
}
Esempio n. 23
0
/*
 * create_ctas_nodata
 *
 * Create CTAS or materialized view when WITH NO DATA is used, starting from
 * the targetlist of the SELECT or view definition.
 */
static ObjectAddress
create_ctas_nodata(List *tlist, IntoClause *into)
{
	List	   *attrList;
	ListCell   *t,
			   *lc;

	/*
	 * Build list of ColumnDefs from non-junk elements of the tlist.  If a
	 * column name list was specified in CREATE TABLE AS, override the column
	 * names in the query.  (Too few column names are OK, too many are not.)
	 */
	attrList = NIL;
	lc = list_head(into->colNames);
	foreach(t, tlist)
	{
		TargetEntry *tle = (TargetEntry *) lfirst(t);

		if (!tle->resjunk)
		{
			ColumnDef  *col;
			char	   *colname;

			if (lc)
			{
				colname = strVal(lfirst(lc));
				lc = lnext(lc);
			}
			else
				colname = tle->resname;

			col = makeColumnDef(colname,
								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.  (We must
			 * check this here because DefineRelation would adopt the type's
			 * default collation rather than complaining.)
			 */
			if (!OidIsValid(col->collOid) &&
				type_is_collatable(col->typeName->typeOid))
				ereport(ERROR,
						(errcode(ERRCODE_INDETERMINATE_COLLATION),
						 errmsg("no collation was derived for column \"%s\" with collatable type %s",
								col->colname,
								format_type_be(col->typeName->typeOid)),
						 errhint("Use the COLLATE clause to set the collation explicitly.")));

			attrList = lappend(attrList, col);
		}
	}
Esempio n. 24
0
int
lskipa1(register char *parens)
{
	register int c;

	for (;;) {
		if (dir < 0 && wcursor == linebuf) {
			if (!lnext())
				return (0);
			break;
		}
		c = *wcursor;
		if (c && (isspace(c) || any(c, parens)))
			break;
		if (!lnext())
			return (0);
		if (dir > 0 && wcursor == linebuf)
			break;
	}
	return (ltosol1(parens));
}
Esempio n. 25
0
/*
 * Checks if any of the 'attnums' is a partition key attribute for rel
 *
 * Sets *used_in_expr if any of the 'attnums' is found to be referenced in some
 * partition key expression.  It's possible for a column to be both used
 * directly and as part of an expression; if that happens, *used_in_expr may
 * end up as either true or false.  That's OK for current uses of this
 * function, because *used_in_expr is only used to tailor the error message
 * text.
 */
bool
has_partition_attrs(Relation rel, Bitmapset *attnums, bool *used_in_expr)
{
	PartitionKey key;
	int			partnatts;
	List	   *partexprs;
	ListCell   *partexprs_item;
	int			i;

	if (attnums == NULL || rel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE)
		return false;

	key = RelationGetPartitionKey(rel);
	partnatts = get_partition_natts(key);
	partexprs = get_partition_exprs(key);

	partexprs_item = list_head(partexprs);
	for (i = 0; i < partnatts; i++)
	{
		AttrNumber	partattno = get_partition_col_attnum(key, i);

		if (partattno != 0)
		{
			if (bms_is_member(partattno - FirstLowInvalidHeapAttributeNumber,
							  attnums))
			{
				if (used_in_expr)
					*used_in_expr = false;
				return true;
			}
		}
		else
		{
			/* Arbitrary expression */
			Node	   *expr = (Node *) lfirst(partexprs_item);
			Bitmapset  *expr_attrs = NULL;

			/* Find all attributes referenced */
			pull_varattnos(expr, 1, &expr_attrs);
			partexprs_item = lnext(partexprs_item);

			if (bms_overlap(attnums, expr_attrs))
			{
				if (used_in_expr)
					*used_in_expr = true;
				return true;
			}
		}
	}

	return false;
}
Esempio n. 26
0
/*
 * To end of word, with operator op and cnt more motions
 * remaining after this.
 */
void
eend(void (*op)())
{
	register int which;

	if (!lnext())
		return;
	while (blank())
		if (!lnext())
			return;
	which = wordch(wcursor);
	while (wordof(which, wcursor)) {
		if (wcursor[1] == 0) {
			wcursor++;
			break;
		}
		if (!lnext())
			return;
	}
	if (op != vchange && op != vdelete && wcursor > linebuf)
		wcursor--;
}
Esempio n. 27
0
File: kheader.c Progetto: klopp/knet
static msg_Header hdr_FindHeader( List headers, const char * key )
{
    msg_Header header = lfirst( headers );
    while( header )
    {
        if( !strcmp( header->name, key ) )
        {
            break;
        }
        header = lnext( headers );
    }
    return header;
}
Esempio n. 28
0
PROGRAMMER * locate_programmer(LISTID programmers, const char * configid)
{
  LNODEID ln1, ln2;
  PROGRAMMER * p = NULL;
  const char * id;
  int found;

  found = 0;

  for (ln1=lfirst(programmers); ln1 && !found; ln1=lnext(ln1)) {
    p = ldata(ln1);
    for (ln2=lfirst(p->id); ln2 && !found; ln2=lnext(ln2)) {
      id = ldata(ln2);
      if (strcasecmp(configid, id) == 0)
        found = 1;
    }
  }

  if (found)
    return p;

  return NULL;
}
Esempio n. 29
0
/* ====== Config / parameters handling functions ====== */
static int
buspirate_parseextparms(struct programmer_t *pgm, LISTID extparms)
{
	LNODEID ln;
	const char *extended_param;
	char reset[10];
	char *preset = reset;	/* for strtok() */
	int spifreq;

	for (ln = lfirst(extparms); ln; ln = lnext(ln)) {
    	extended_param = ldata(ln);
		if (strcmp(extended_param, "ascii") == 0) {
			pgm->flag |= BP_FLAG_XPARM_FORCE_ASCII;
			continue;
		}
		if (sscanf(extended_param, "spifreq=%d", &spifreq) == 1) {
			if (spifreq & (~0x07)) {
				fprintf(stderr, "BusPirate: spifreq must be between 0 and 7.\n");
				fprintf(stderr, "BusPirate: see BusPirate manual for details.\n");
				return -1;
			}
			PDATA(pgm)->spifreq = spifreq;
			pgm->flag |= BP_FLAG_XPARM_SPIFREQ;
			continue;
		}

		if (sscanf(extended_param, "reset=%s", reset) == 1) {
			char *resetpin;
			while ((resetpin = strtok(preset, ","))) {
				preset = NULL;	/* for subsequent strtok() calls */
				if (strcasecmp(resetpin, "cs") == 0)
					PDATA(pgm)->reset |= BP_RESET_CS;
				else if (strcasecmp(resetpin, "aux") == 0 || strcasecmp(reset, "aux1") == 0)
					PDATA(pgm)->reset |= BP_RESET_AUX;
				else if (strcasecmp(resetpin, "aux2") == 0)
					PDATA(pgm)->reset |= BP_RESET_AUX2;
				else {
					fprintf(stderr, "BusPirate: reset must be either CS or AUX.\n");
					return -1;
				}
			}
			pgm->flag |= BP_FLAG_XPARM_RESET;
			continue;
		}
	}

	return 0;
}
Esempio n. 30
0
static int ft245r_parseextparms(PROGRAMMER * pgm, LISTID extparms)
{
  LNODEID ln;
  const char *extended_param;
  int rv = 0;

  for (ln = lfirst(extparms); ln; ln = lnext(ln)) {
    extended_param = ldata(ln);

    if (strncmp(extended_param, "serial=", strlen("serial=")) == 0) {
      if (strlen(extended_param) != (strlen("serial=") + 8)){
        avrdude_message(MSG_INFO,
                "%s: ft245r_parseextparms(): serial has invalid length '%s'\n",
                progname, extended_param);
        rv = -1;
        continue;

      }
      char serial[9] = {0};
      if ((sscanf(extended_param, "serial=%s", serial)
          != 1) && (strlen(serial) == 8)) {
        avrdude_message(MSG_INFO,
                "%s: ft245r_parseextparms(): invalid serial '%s'\n",
                progname, serial);
        rv = -1;
        continue;
      }
      if (verbose >= 2) {
        avrdude_message(MSG_INFO,
                "%s: ft245r_parseextparms(): serial number parsed as:\n"
                "%s %s\n",
                progname,
                progbuf, serial);
      }
      strcpy(pgm->usbsn, serial);

      continue;
    }

    avrdude_message(MSG_INFO,
            "%s: ft245r_parseextparms(): invalid extended parameter '%s'\n",
            progname, extended_param);
    rv = -1;
  }

  return rv;
}