예제 #1
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));
	}
예제 #2
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));
	}
예제 #3
0
파일: label.c 프로젝트: LDuderino/postgres
/*
 * sepgsql_xact_callback
 *
 * A callback routine of transaction commit/abort/prepare.  Commit or abort
 * changes in the client_label_pending list.
 */
static void
sepgsql_xact_callback(XactEvent event, void *arg)
{
	if (event == XACT_EVENT_COMMIT)
	{
		if (client_label_pending != NIL)
		{
			pending_label *plabel = llast(client_label_pending);
			char	   *new_label;

			if (plabel->label)
				new_label = MemoryContextStrdup(TopMemoryContext,
												plabel->label);
			else
				new_label = NULL;

			if (client_label_committed)
				pfree(client_label_committed);

			client_label_committed = new_label;

			/*
			 * XXX - Note that items of client_label_pending are allocated on
			 * CurTransactionContext, thus, all acquired memory region shall
			 * be released implicitly.
			 */
			client_label_pending = NIL;
		}
	}
	else if (event == XACT_EVENT_ABORT)
		client_label_pending = NIL;
}
예제 #4
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));
	}
예제 #5
0
void
joinQueryRTEs(Query *query)
{
        ListCell *lc;
        JoinExpr *newJoin;
        List *fromItems;
        List *subJoins;

        /* if query has only one or no range table entry return */
        if (list_length(query->jointree->fromlist) <= 1)
                return;

        subJoins = NIL;
    fromItems = query->jointree->fromlist;
    query->jointree->fromlist = NIL;

    /* create a join tree that joins all from items */
    lc = fromItems->head;

    newJoin = createJoinExpr (query, JOIN_INNER);
    newJoin->quals = (Node *) makeBoolConst(true, false);
    newJoin->larg = (Node *) lfirst(lc);
    lc = lc ->next;
    newJoin->rarg = (Node *) lfirst(lc);

    subJoins = lappend(subJoins, newJoin);

    for(lc = lc->next; lc != NULL; lc = lc->next)
        {
        newJoin = createJoinExpr (query, JOIN_INNER);

                /* set join condition to true */
                newJoin->quals = (Node *) makeBoolConst(true, false);

                /* set children */
                newJoin->rarg = (Node *) llast(subJoins);
                newJoin->larg = (Node *) lfirst(lc);

                /* append to join list */
                subJoins = lappend(subJoins, newJoin);
        }

    /* create from list as new top join */
    query->jointree->fromlist = list_make1(newJoin);

    adaptRTEsForJoins(subJoins, query, "query_rte_joined");
}
예제 #6
0
파일: label.c 프로젝트: LDuderino/postgres
/*
 * sepgsql_get_client_label
 *
 * Returns the current security label of the client.  All code should use this
 * routine to get the current label, instead of referring to the client_label_*
 * variables above.
 */
char *
sepgsql_get_client_label(void)
{
	/* trusted procedure client label override */
	if (client_label_func)
		return client_label_func;

	/* uncommitted sepgsql_setcon() value */
	if (client_label_pending)
	{
		pending_label *plabel = llast(client_label_pending);

		if (plabel->label)
			return plabel->label;
	}
	else if (client_label_committed)
		return client_label_committed;	/* set by sepgsql_setcon() committed */

	/* default label */
	Assert(client_label_peer != NULL);
	return client_label_peer;
}
예제 #7
0
  virtual std::string operator()(PtbPsTree::const_depth_first_iterator& cdfi,
                                 const PtbPsTree& tree) const
  {
    typedef PtbPsTree::const_depth_first_iterator const_iterator;
    typedef PtbPsTree::const_leaf_iterator const_leaf_iterator;

    std::stringstream ss(std::stringstream::in |std::stringstream::out);
    const_iterator copy = cdfi;
    const_iterator copycopy = copy;

    ss << *cdfi << "^";

    //don't process terminals and preterminals
    if(copy->leaf()) {
      return "";
    }
    else {
      copycopy.down_first();
      if(copycopy->leaf()) {
        return "";
      }
    }

    unsigned n = tree.subtree(cdfi).number_of_leaves();
    // bin 1,2,3,4,5, [6,10[, >=10
    if(n >= 10) n = 10;
    else if(n>5) n = 6;

    ss << n << "^";

    //go to the first daughter
    do {
      copy.down_first();
    }
    while(!copy->leaf());



    //go to the last daughter
    copycopy = cdfi;
    do {
      copycopy.down_last();
    }
    while(!copycopy->leaf());

    const_leaf_iterator lfirst(&tree, copy.get_node());
    const_leaf_iterator llast(&tree,  copycopy.get_node());



    for (unsigned i = 0; i < nfirst; ++i)
      {
        const_iterator d = lfirst;
        d.up();
        ss << *d << "^";
        ++lfirst;
        if(lfirst == tree.lend())
          break;
      }

    ss << "<>";

    for (unsigned i = 0; i < nlast; ++i)
      {
        const_iterator d = llast;
        d.up();
        ss << *d << "^";
        --llast;
        if(llast == tree.lend())
          break;
      }

    return ss.str();
  }
예제 #8
0
/* ----------------------------------------------------------------
 *
 * ----------------------------------------------------------------
 */
Datum
int4notin(PG_FUNCTION_ARGS)
{
	int32		not_in_arg = PG_GETARG_INT32(0);
	text	   *relation_and_attr = PG_GETARG_TEXT_P(1);
	List	   *names;
	int			nnames;
	RangeVar   *relrv;
	char	   *attribute;
	Relation	relation_to_scan;
	int32		integer_value;
	HeapTuple	current_tuple;
	HeapScanDesc scan_descriptor;
	bool		isNull,
				retval;
	int			attrid;
	Datum		value;

	/* Parse the argument */

	names = textToQualifiedNameList(relation_and_attr);
	nnames = list_length(names);
	if (nnames < 2)
		ereport(ERROR,
				(errcode(ERRCODE_INVALID_NAME),
				 errmsg("invalid name syntax"),
				 errhint("Must provide \"relationname.columnname\".")));
	attribute = strVal(llast(names));
	names = list_truncate(names, nnames - 1);
	relrv = makeRangeVarFromNameList(names);

	/* Open the relation and get a relation descriptor */
	relation_to_scan = heap_openrv(relrv, AccessShareLock);

	/* Find the column to search */
	attrid = attnameAttNum(relation_to_scan, attribute, true);

	scan_descriptor = heap_beginscan(relation_to_scan, SnapshotNow,
									 0, (ScanKey) NULL);

	retval = true;

	/* do a scan of the relation, and do the check */
	while ((current_tuple = heap_getnext(scan_descriptor, ForwardScanDirection)) != NULL)
	{
		value = heap_getattr(current_tuple,
							 (AttrNumber) attrid,
							 RelationGetDescr(relation_to_scan),
							 &isNull);
		if (isNull)
			continue;
		integer_value = DatumGetInt32(value);
		if (not_in_arg == integer_value)
		{
			retval = false;
			break;				/* can stop scanning now */
		}
	}

	/* close the relation */
	heap_endscan(scan_descriptor);
	heap_close(relation_to_scan, AccessShareLock);

	PG_RETURN_BOOL(retval);
}
예제 #9
0
파일: parse_target.c 프로젝트: nskyzh/gpdb
/*
 * 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;
	ParseStateBreadCrumb    savebreadcrumb;

	/* CDB: Push error location stack.  Must pop before return! */
	Assert(pstate);
	savebreadcrumb = pstate->p_breadcrumb;
	pstate->p_breadcrumb.pop = &savebreadcrumb;

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

		/* CDB: Drop a breadcrumb in case of error. */
		pstate->p_breadcrumb.node = (Node *)res;

		/*
		 * 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));
	}
예제 #10
0
/*
 * CStoreBeginWrite initializes a cstore data load operation and returns a table
 * handle. This handle should be used for adding the row values and finishing the
 * data load operation. If the cstore footer file already exists, we read the
 * footer and then seek to right after the last stripe  where the new stripes
 * will be added.
 */
TableWriteState *
CStoreBeginWrite(const char *filename, CompressionType compressionType,
				 uint64 stripeMaxRowCount, uint32 blockRowCount,
				 TupleDesc tupleDescriptor)
{
	TableWriteState *writeState = NULL;
	FILE *tableFile = NULL;
	StringInfo tableFooterFilename = NULL;
	TableFooter *tableFooter = NULL;
	FmgrInfo **comparisonFunctionArray = NULL;
	MemoryContext stripeWriteContext = NULL;
	uint64 currentFileOffset = 0;
	uint32 columnCount = 0;
	uint32 columnIndex = 0;
	struct stat statBuffer;
	int statResult = 0;
	bool *columnMaskArray = NULL;
	ColumnBlockData **blockData = NULL;

	tableFooterFilename = makeStringInfo();
	appendStringInfo(tableFooterFilename, "%s%s", filename, CSTORE_FOOTER_FILE_SUFFIX);

	statResult = stat(tableFooterFilename->data, &statBuffer);
	if (statResult < 0)
	{
		tableFile = AllocateFile(filename, "w");
		if (tableFile == NULL)
		{
			ereport(ERROR, (errcode_for_file_access(),
							errmsg("could not open file \"%s\" for writing: %m",
								   filename)));
		}

		tableFooter = palloc0(sizeof(TableFooter));
		tableFooter->blockRowCount = blockRowCount;
		tableFooter->stripeMetadataList = NIL;
	}
	else
	{
		tableFile = AllocateFile(filename, "r+");
		if (tableFile == NULL)
		{
			ereport(ERROR, (errcode_for_file_access(),
							errmsg("could not open file \"%s\" for writing: %m",
								   filename)));
		}

		tableFooter = CStoreReadFooter(tableFooterFilename);
	}

	/*
	 * If stripeMetadataList is not empty, jump to the position right after
	 * the last position.
	 */
	if (tableFooter->stripeMetadataList != NIL)
	{
		StripeMetadata *lastStripe = NULL;
		uint64 lastStripeSize = 0;
		int fseekResult = 0;

		lastStripe = llast(tableFooter->stripeMetadataList);
		lastStripeSize += lastStripe->skipListLength;
		lastStripeSize += lastStripe->dataLength;
		lastStripeSize += lastStripe->footerLength;

		currentFileOffset = lastStripe->fileOffset + lastStripeSize;

		errno = 0;
		fseekResult = fseeko(tableFile, currentFileOffset, SEEK_SET);
		if (fseekResult != 0)
		{
			ereport(ERROR, (errcode_for_file_access(),
							errmsg("could not seek in file \"%s\": %m", filename)));
		}
	}

	/* get comparison function pointers for each of the columns */
	columnCount = tupleDescriptor->natts;
	comparisonFunctionArray = palloc0(columnCount * sizeof(FmgrInfo *));
	for (columnIndex = 0; columnIndex < columnCount; columnIndex++)
	{
		FmgrInfo *comparisonFunction = NULL;
		FormData_pg_attribute *attributeForm = tupleDescriptor->attrs[columnIndex];

		if (!attributeForm->attisdropped)
		{
			Oid typeId = attributeForm->atttypid;

			comparisonFunction = GetFunctionInfoOrNull(typeId, BTREE_AM_OID, BTORDER_PROC);
		}

		comparisonFunctionArray[columnIndex] = comparisonFunction;
	}

	/*
	 * We allocate all stripe specific data in the stripeWriteContext, and
	 * reset this memory context once we have flushed the stripe to the file.
	 * This is to avoid memory leaks.
	 */
	stripeWriteContext = AllocSetContextCreate(CurrentMemoryContext,
											   "Stripe Write Memory Context",
											   ALLOCSET_DEFAULT_MINSIZE,
											   ALLOCSET_DEFAULT_INITSIZE,
											   ALLOCSET_DEFAULT_MAXSIZE);

	columnMaskArray = palloc(columnCount * sizeof(bool));
	memset(columnMaskArray, true, columnCount);

	blockData = CreateEmptyBlockDataArray(columnCount, columnMaskArray, blockRowCount);

	writeState = palloc0(sizeof(TableWriteState));
	writeState->tableFile = tableFile;
	writeState->tableFooterFilename = tableFooterFilename;
	writeState->tableFooter = tableFooter;
	writeState->compressionType = compressionType;
	writeState->stripeMaxRowCount = stripeMaxRowCount;
	writeState->tupleDescriptor = tupleDescriptor;
	writeState->currentFileOffset = currentFileOffset;
	writeState->comparisonFunctionArray = comparisonFunctionArray;
	writeState->stripeBuffers = NULL;
	writeState->stripeSkipList = NULL;
	writeState->stripeWriteContext = stripeWriteContext;
	writeState->blockDataArray = blockData;
	writeState->compressionBuffer = NULL;

	return writeState;
}