Example #1
0
bool Variant::toString(std::string &retVal)
{
    switch (type())
    {
    case VT_Undefined:
        retVal = "undefined";
        return false;
    case VT_Null:
    case VT_Type:
    case VT_Persistent:
        retVal = "null";
        return false;
    case VT_Boolean:
        retVal = m_Val.boolVal ? "true" : "false";
        return true;
    case VT_Integer:
    {
        char str[STRING_BUF_SIZE];

        sprintf(str, "%d", m_Val.intVal);
        retVal = str;

        return true;
    }
    case VT_Long:
    {
        char str[STRING_BUF_SIZE];

#ifdef _WIN32
        sprintf(str, "%lld", m_Val.longVal);
#else
        sprintf(str, "%lld", (long long) m_Val.longVal);
#endif

        retVal = str;

        return true;
    }
    case VT_Number:
    {
        char str[STRING_BUF_SIZE];

        sprintf(str, "%.16g", m_Val.dblVal);
        retVal = str;

        return true;
    }
    case VT_Date:
        dateVal().toGMTString(retVal);
        return true;
    case VT_Object:
        return false;
    case VT_String:
        retVal = strVal();
        return true;
    case VT_JSValue:
        return false;
    }

    return false;
}
Example #2
0
/*
 * intorel_startup --- executor startup
 */
static void
intorel_startup(DestReceiver *self, int operation, TupleDesc typeinfo)
{
	DR_intorel *myState = (DR_intorel *) self;
	IntoClause *into = myState->into;
	bool		is_matview;
	char		relkind;
	CreateStmt *create;
	Oid			intoRelationId;
	Relation	intoRelationDesc;
	RangeTblEntry *rte;
	Datum		toast_options;
	ListCell   *lc;
	int			attnum;
	static char *validnsps[] = HEAP_RELOPT_NAMESPACES;

	Assert(into != NULL);		/* else somebody forgot to set it */

	/* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */
	is_matview = (into->viewQuery != NULL);
	relkind = is_matview ? RELKIND_MATVIEW : RELKIND_RELATION;

	/*
	 * Create the target relation by faking up a CREATE TABLE parsetree and
	 * passing it to DefineRelation.
	 */
	create = makeNode(CreateStmt);
	create->relation = into->rel;
	create->tableElts = NIL;	/* will fill below */
	create->inhRelations = NIL;
	create->ofTypename = NULL;
	create->constraints = NIL;
	create->options = into->options;
	create->oncommit = into->onCommit;
	create->tablespacename = into->tableSpaceName;
	create->if_not_exists = false;

	/*
	 * Build column definitions using "pre-cooked" type and collation info. If
	 * a column name list was specified in CREATE TABLE AS, override the
	 * column names derived from the query.  (Too few column names are OK, too
	 * many are not.)
	 */
	lc = list_head(into->colNames);
	for (attnum = 0; attnum < typeinfo->natts; attnum++)
	{
		Form_pg_attribute attribute = typeinfo->attrs[attnum];
		ColumnDef  *col = makeNode(ColumnDef);
		TypeName   *coltype = makeNode(TypeName);

		if (lc)
		{
			col->colname = strVal(lfirst(lc));
			lc = lnext(lc);
		}
		else
			col->colname = NameStr(attribute->attname);
		col->typeName = coltype;
		col->inhcount = 0;
		col->is_local = true;
		col->is_not_null = false;
		col->is_from_type = false;
		col->storage = 0;
		col->raw_default = NULL;
		col->cooked_default = NULL;
		col->collClause = NULL;
		col->collOid = attribute->attcollation;
		col->constraints = NIL;
		col->fdwoptions = NIL;

		coltype->names = NIL;
		coltype->typeOid = attribute->atttypid;
		coltype->setof = false;
		coltype->pct_type = false;
		coltype->typmods = NIL;
		coltype->typemod = attribute->atttypmod;
		coltype->arrayBounds = NIL;
		coltype->location = -1;

		/*
		 * 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(coltype->typeOid))
			ereport(ERROR,
					(errcode(ERRCODE_INDETERMINATE_COLLATION),
					 errmsg("no collation was derived for column \"%s\" with collatable type %s",
							col->colname, format_type_be(coltype->typeOid)),
					 errhint("Use the COLLATE clause to set the collation explicitly.")));

		create->tableElts = lappend(create->tableElts, col);
	}

	if (lc != NULL)
		ereport(ERROR,
				(errcode(ERRCODE_SYNTAX_ERROR),
				 errmsg("too many column names were specified")));

	/*
	 * Actually create the target table
	 */
	intoRelationId = DefineRelation(create, relkind, InvalidOid);

	/*
	 * If necessary, create a TOAST table for the target table.  Note that
	 * AlterTableCreateToastTable ends with CommandCounterIncrement(), so that
	 * the TOAST table will be visible for insertion.
	 */
	CommandCounterIncrement();

	/* parse and validate reloptions for the toast table */
	toast_options = transformRelOptions((Datum) 0,
										create->options,
										"toast",
										validnsps,
										true, false);

	(void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true);

	AlterTableCreateToastTable(intoRelationId, toast_options);

	/* Create the "view" part of a materialized view. */
	if (is_matview)
	{
		/* StoreViewQuery scribbles on tree, so make a copy */
		Query	   *query = (Query *) copyObject(into->viewQuery);

		StoreViewQuery(intoRelationId, query, false);
		CommandCounterIncrement();
	}

	/*
	 * Finally we can open the target table
	 */
	intoRelationDesc = heap_open(intoRelationId, AccessExclusiveLock);

	/*
	 * Check INSERT permission on the constructed table.
	 *
	 * XXX: It would arguably make sense to skip this check if into->skipData
	 * is true.
	 */
	rte = makeNode(RangeTblEntry);
	rte->rtekind = RTE_RELATION;
	rte->relid = intoRelationId;
	rte->relkind = relkind;
	rte->requiredPerms = ACL_INSERT;

	for (attnum = 1; attnum <= intoRelationDesc->rd_att->natts; attnum++)
		rte->modifiedCols = bms_add_member(rte->modifiedCols,
								attnum - FirstLowInvalidHeapAttributeNumber);

	ExecCheckRTPerms(list_make1(rte), true);

	/*
	 * Tentatively mark the target as populated, if it's a matview and we're
	 * going to fill it; otherwise, no change needed.
	 */
	if (is_matview && !into->skipData)
		SetMatViewPopulatedState(intoRelationDesc, true);

	/*
	 * Fill private fields of myState for use by later routines
	 */
	myState->rel = intoRelationDesc;
	myState->output_cid = GetCurrentCommandId(true);

	/*
	 * We can skip WAL-logging the insertions, unless PITR or streaming
	 * replication is in use. We can skip the FSM in any case.
	 */
	myState->hi_options = HEAP_INSERT_SKIP_FSM |
		(XLogIsNeeded() ? 0 : HEAP_INSERT_SKIP_WAL);
	myState->bistate = GetBulkInsertState();

	/* Not using WAL requires smgr_targblock be initially invalid */
	Assert(RelationGetTargetBlock(intoRelationDesc) == InvalidBlockNumber);
}
Example #3
0
/*
 * EnumValuesCreate
 *		Create an entry in pg_enum for each of the supplied enum values.
 *
 * vals is a list of Value strings.
 */
void
EnumValuesCreate(Oid enumTypeOid, List *vals)
{
	Relation	pg_enum;
	NameData	enumlabel;
	Oid		   *oids;
	int			elemno,
				num_elems;
	Datum		values[Natts_pg_enum];
	bool		nulls[Natts_pg_enum];
	ListCell   *lc;
	HeapTuple	tup;

	num_elems = list_length(vals);

	/*
	 * We do not bother to check the list of values for duplicates --- if you
	 * have any, you'll get a less-than-friendly unique-index violation. It is
	 * probably not worth trying harder.
	 */

	pg_enum = heap_open(EnumRelationId, RowExclusiveLock);

	/*
	 * Allocate OIDs for the enum's members.
	 *
	 * While this method does not absolutely guarantee that we generate no
	 * duplicate OIDs (since we haven't entered each oid into the table before
	 * allocating the next), trouble could only occur if the OID counter wraps
	 * all the way around before we finish. Which seems unlikely.
	 */
	oids = (Oid *) palloc(num_elems * sizeof(Oid));

	for (elemno = 0; elemno < num_elems; elemno++)
	{
		/*
		 * We assign even-numbered OIDs to all the new enum labels.  This
		 * tells the comparison functions the OIDs are in the correct sort
		 * order and can be compared directly.
		 */
		Oid			new_oid;

		do
		{
			new_oid = GetNewOid(pg_enum);
		} while (new_oid & 1);
		oids[elemno] = new_oid;
	}

	/* sort them, just in case OID counter wrapped from high to low */
	qsort(oids, num_elems, sizeof(Oid), oid_cmp);

	/* and make the entries */
	memset(nulls, false, sizeof(nulls));

	elemno = 0;
	foreach(lc, vals)
	{
		char	   *lab = strVal(lfirst(lc));

		/*
		 * labels are stored in a name field, for easier syscache lookup, so
		 * check the length to make sure it's within range.
		 */
		if (strlen(lab) > (NAMEDATALEN - 1))
			ereport(ERROR,
					(errcode(ERRCODE_INVALID_NAME),
					 errmsg("invalid enum label \"%s\"", lab),
					 errdetail("Labels must be %d characters or less.",
							   NAMEDATALEN - 1)));

		values[Anum_pg_enum_enumtypid - 1] = ObjectIdGetDatum(enumTypeOid);
		values[Anum_pg_enum_enumsortorder - 1] = Float4GetDatum(elemno + 1);
		namestrcpy(&enumlabel, lab);
		values[Anum_pg_enum_enumlabel - 1] = NameGetDatum(&enumlabel);

		tup = heap_form_tuple(RelationGetDescr(pg_enum), values, nulls);
		HeapTupleSetOid(tup, oids[elemno]);

		simple_heap_insert(pg_enum, tup);
		CatalogUpdateIndexes(pg_enum, tup);
		heap_freetuple(tup);

		elemno++;
	}
Example #4
0
/*
 * GpPolicyFetch
 *
 * Looks up the distribution policy of given relation from
 * gp_distribution_policy table (or by implicit rules for external tables)
 * Returns an GpPolicy object, allocated in the specified context, containing
 * the information.
 *
 * The caller is responsible for passing in a valid relation oid.  This
 * function does not check, and assigns a policy of type POLICYTYPE_ENTRY
 * for any oid not found in gp_distribution_policy.
 */
GpPolicy *
GpPolicyFetch(MemoryContext mcxt, Oid tbloid)
{
	GpPolicy  *policy = NULL;	/* The result */
	Relation	gp_policy_rel;
	cqContext	cqc;
	HeapTuple	gp_policy_tuple = NULL;

	/*
	 * Skip if qExec or utility mode.
	 */
	if (Gp_role != GP_ROLE_DISPATCH)
	{
		policy = (GpPolicy *) MemoryContextAlloc(mcxt, SizeOfGpPolicy(0));
		policy->ptype = POLICYTYPE_ENTRY;
		policy->nattrs = 0;

		return policy;
	}

	/*
	 * EXECUTE-type external tables have an "ON ..." specification, stored
	 * in pg_exttable.location. See if it's "MASTER_ONLY". Other types of
	 * external tables have a gp_distribution_policy row, like normal tables.
	 */
	if (get_rel_relstorage(tbloid) == RELSTORAGE_EXTERNAL)
	{
		/*
		 * An external table really should have a pg_exttable entry, but
		 * there's currently a transient state during creation of an external
		 * table, where the pg_class entry has been created, and its loaded
		 * into the relcache, before the pg_exttable entry has been created.
		 * Silently ignore missing pg_exttable rows to cope with that.
		 */
		ExtTableEntry *e = GetExtTableEntryIfExists(tbloid);

		/*
		 * Writeable external tables have gp_distribution_policy entries,
		 * like regular tables. Readable external tables are implicitly
		 * randomly distributed, except for "EXECUTE ... ON MASTER" ones.
		 */
		if (e && !e->iswritable)
		{
			if (e->command)
			{
				char	   *on_clause = (char *) strVal(linitial(e->locations));

				if (strcmp(on_clause, "MASTER_ONLY") == 0)
				{
					policy = (GpPolicy *) MemoryContextAlloc(mcxt, SizeOfGpPolicy(0));
					policy->ptype = POLICYTYPE_ENTRY;
					policy->nattrs = 0;
					return policy;
				}
			}
			policy = (GpPolicy *) MemoryContextAlloc(mcxt, SizeOfGpPolicy(0));
			policy->ptype = POLICYTYPE_PARTITIONED;
			policy->nattrs = 0;
			return policy;
		}
	}

	/*
	 * We need to read the gp_distribution_policy table
	 */
	gp_policy_rel = heap_open(GpPolicyRelationId, AccessShareLock);

	/*
	 * Select by value of the localoid field
	 */
	gp_policy_tuple = caql_getfirst(
			caql_addrel(cqclr(&cqc), gp_policy_rel), 
			cql("SELECT * FROM gp_distribution_policy "
				" WHERE localoid = :1 ",
				ObjectIdGetDatum(tbloid)));

	/*
	 * Read first (and only) tuple
	 */
	if (HeapTupleIsValid(gp_policy_tuple))
	{
		bool		isNull;
		Datum		attr;
		int			i,
					nattrs = 0;
		int16	   *attrnums = NULL;

		/*
		 * Get the attributes on which to partition.
		 */
		attr = heap_getattr(gp_policy_tuple, Anum_gp_policy_attrnums, 
							RelationGetDescr(gp_policy_rel), &isNull);

		/*
		 * Get distribution keys only if this table has a policy.
		 */
		if(!isNull)
		{
			extract_INT2OID_array(attr, &nattrs, &attrnums);
			Assert(nattrs >= 0);
		}

		/* Create an GpPolicy object. */
		policy = (GpPolicy *) MemoryContextAlloc(mcxt, SizeOfGpPolicy(nattrs));
		policy->ptype = POLICYTYPE_PARTITIONED;
		policy->nattrs = nattrs;
		for (i = 0; i < nattrs; i++)
		{
			policy->attrs[i] = attrnums[i];
		}
	}

	/*
	 * Cleanup the scan and relation objects.
	 */
	heap_close(gp_policy_rel, AccessShareLock);

	/* Interpret absence of a valid policy row as POLICYTYPE_ENTRY */
	if (policy == NULL)
	{
		policy = (GpPolicy *) MemoryContextAlloc(mcxt, SizeOfGpPolicy(0));
		policy->ptype = POLICYTYPE_ENTRY;
		policy->nattrs = 0;
	}

	return policy;
}                               /* GpPolicyFetch */
Example #5
0
/* ----------------------------------------------------------------
 *		ExecInitFunctionScan
 * ----------------------------------------------------------------
 */
FunctionScanState *
ExecInitFunctionScan(FunctionScan *node, EState *estate, int eflags)
{
	FunctionScanState *scanstate;
	RangeTblEntry *rte;
	Oid			funcrettype;
	TypeFuncClass functypclass;
	TupleDesc	tupdesc = NULL;

	/*
	 * FunctionScan should not have any children.
	 */
	Assert(outerPlan(node) == NULL);
	Assert(innerPlan(node) == NULL);

	/*
	 * create new ScanState for node
	 */
	scanstate = makeNode(FunctionScanState);
	scanstate->ss.ps.plan = (Plan *) node;
	scanstate->ss.ps.state = estate;

	/*
	 * Miscellaneous initialization
	 *
	 * create expression context for node
	 */
	ExecAssignExprContext(estate, &scanstate->ss.ps);

#define FUNCTIONSCAN_NSLOTS 2

	/*
	 * tuple table initialization
	 */
	ExecInitResultTupleSlot(estate, &scanstate->ss.ps);
	ExecInitScanTupleSlot(estate, &scanstate->ss);

	/*
	 * initialize child expressions
	 */
	scanstate->ss.ps.targetlist = (List *)
		ExecInitExpr((Expr *) node->scan.plan.targetlist,
					 (PlanState *) scanstate);
	scanstate->ss.ps.qual = (List *)
		ExecInitExpr((Expr *) node->scan.plan.qual,
					 (PlanState *) scanstate);

	/* Check if targetlist or qual contains a var node referencing the ctid column */
	scanstate->cdb_want_ctid = contain_ctid_var_reference(&node->scan);

    ItemPointerSet(&scanstate->cdb_fake_ctid, 0, 0);
    ItemPointerSet(&scanstate->cdb_mark_ctid, 0, 0);

	/*
	 * get info about function
	 */
	rte = rt_fetch(node->scan.scanrelid, estate->es_range_table);
	Assert(rte->rtekind == RTE_FUNCTION);

	/*
	 * Now determine if the function returns a simple or composite type, and
	 * build an appropriate tupdesc.
	 */
	functypclass = get_expr_result_type(rte->funcexpr,
										&funcrettype,
										&tupdesc);

	if (functypclass == TYPEFUNC_COMPOSITE)
	{
		/* Composite data type, e.g. a table's row type */
		Assert(tupdesc);
		/* Must copy it out of typcache for safety */
		tupdesc = CreateTupleDescCopy(tupdesc);
	}
	else if (functypclass == TYPEFUNC_SCALAR)
	{
		/* Base data type, i.e. scalar */
		char	   *attname = strVal(linitial(rte->eref->colnames));

		tupdesc = CreateTemplateTupleDesc(1, false);
		TupleDescInitEntry(tupdesc,
						   (AttrNumber) 1,
						   attname,
						   funcrettype,
						   -1,
						   0);
	}
	else if (functypclass == TYPEFUNC_RECORD)
	{
		tupdesc = BuildDescFromLists(rte->eref->colnames,
									 rte->funccoltypes,
									 rte->funccoltypmods);
	}
	else
	{
		/* crummy error message, but parser should have caught this */
		elog(ERROR, "function in FROM has unsupported return type");
	}

	/*
	 * For RECORD results, make sure a typmod has been assigned.  (The
	 * function should do this for itself, but let's cover things in case it
	 * doesn't.)
	 */
	BlessTupleDesc(tupdesc);

	scanstate->tupdesc = tupdesc;
	ExecAssignScanType(&scanstate->ss, tupdesc);

	/*
	 * Other node-specific setup
	 */
	scanstate->tuplestorestate = NULL;
	scanstate->funcexpr = ExecInitExpr((Expr *) rte->funcexpr,
									   (PlanState *) scanstate);

	/*
	 * Initialize result tuple type and projection info.
	 */
	ExecAssignResultTypeFromTL(&scanstate->ss.ps);
	ExecAssignScanProjectionInfo(&scanstate->ss);

	initGpmonPktForFunctionScan((Plan *)node, &scanstate->ss.ps.gpmon_pkt, estate);
	
	if (gp_resqueue_memory_policy != RESQUEUE_MEMORY_POLICY_NONE)
	{
		SPI_ReserveMemory(((Plan *)node)->operatorMemKB * 1024L);
	}

	return scanstate;
}
Example #6
0
/*
 * Drop a table space
 *
 * Be careful to check that the tablespace is empty.
 */
void
RemoveTableSpace(List *names, DropBehavior behavior, bool missing_ok)
{
	char	   *tablespacename;
	Relation	rel;
	HeapTuple	tuple;
	cqContext	cqc;
	cqContext  *pcqCtx;
	Oid			tablespaceoid;
	int32		count;
	RelFileNode	relfilenode;
	DbDirNode	dbDirNode;
	PersistentFileSysState persistentState;
	ItemPointerData persistentTid;
	int64		persistentSerialNum;

	/*
	 * General DROP (object) syntax allows fully qualified names, but
	 * tablespaces are global objects that do not live in schemas, so
	 * it is a syntax error if a fully qualified name was given.
	 */
	if (list_length(names) != 1)
		ereport(ERROR,
				(errcode(ERRCODE_SYNTAX_ERROR),
				 errmsg("tablespace name may not be qualified")));
	tablespacename = strVal(linitial(names));

	/* Disallow CASCADE */
	if (behavior == DROP_CASCADE)
		ereport(ERROR,
				(errcode(ERRCODE_SYNTAX_ERROR),
				 errmsg("syntax at or near \"cascade\"")));

	/*
	 * Find the target tuple
	 */
	rel = heap_open(TableSpaceRelationId, RowExclusiveLock);

	pcqCtx = caql_addrel(cqclr(&cqc), rel);

	tuple = caql_getfirst(
			pcqCtx,
			cql("SELECT * FROM pg_tablespace "
				 " WHERE spcname = :1 "
				 " FOR UPDATE ",
				CStringGetDatum(tablespacename)));

	if (!HeapTupleIsValid(tuple))
	{
		/* No such tablespace, no need to hold the lock */
		heap_close(rel, RowExclusiveLock);

		if (!missing_ok)
		{
			ereport(ERROR,
					(errcode(ERRCODE_UNDEFINED_OBJECT),
					 errmsg("tablespace \"%s\" does not exist",
							tablespacename)));
		}
		else
		{
			ereport(NOTICE,
					(errmsg("tablespace \"%s\" does not exist, skipping",
							tablespacename)));
		}
		return;
	}

	tablespaceoid = HeapTupleGetOid(tuple);

	/* Must be tablespace owner */
	if (!pg_tablespace_ownercheck(tablespaceoid, GetUserId()))
		aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TABLESPACE,
					   tablespacename);

	/* Disallow drop of the standard tablespaces, even by superuser */
	if (tablespaceoid == GLOBALTABLESPACE_OID ||
		tablespaceoid == DEFAULTTABLESPACE_OID)
		aclcheck_error(ACLCHECK_NO_PRIV, ACL_KIND_TABLESPACE,
					   tablespacename);

	/*
	 * Check for any databases or relations defined in this tablespace, this
	 * is logically the same as checkSharedDependencies, however we don't
	 * actually track these in pg_shdepend, instead we lookup this information
	 * in the gp_persistent_database/relation_node tables.
	 */
	/* ... */

	/*
	 * Remove the pg_tablespace tuple (this will roll back if we fail below)
	 */
	caql_delete_current(pcqCtx);

	/*
	 * Remove any comments on this tablespace.
	 */
	DeleteSharedComments(tablespaceoid, TableSpaceRelationId);

	/*
	 * Remove dependency on owner.
	 *
	 * If shared dependencies are added between filespace <=> tablespace
	 * they will be deleted as well.
	 */
	deleteSharedDependencyRecordsFor(TableSpaceRelationId, tablespaceoid);

	/* MPP-6929: metadata tracking */
	if (Gp_role == GP_ROLE_DISPATCH)
		MetaTrackDropObject(TableSpaceRelationId,
							tablespaceoid);

	/*
	 * Acquire TablespaceCreateLock to ensure that no
	 * MirroredFileSysObj_JustInTimeDbDirCreate is running concurrently.
	 */
	LWLockAcquire(TablespaceCreateLock, LW_EXCLUSIVE);

	/*
	 * Check for any relations still defined in the tablespace.
	 */
	PersistentRelation_CheckTablespace(tablespaceoid, &count, &relfilenode);
	if (count > 0)
	{
		ereport(ERROR,
				(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
				 errmsg("tablespace \"%s\" is not empty", tablespacename)));
	}

	/*
	 * Schedule the removal the physical infrastructure.
	 *
	 * Note: This only schedules the delete, the delete won't actually occur
	 * until after the transaction has comitted.  This should however do
	 * everything it can to assure that the delete will occur sucessfully,
	 * e.g. check permissions etc.
	 */

    /*
	 * Schedule all persistent database directory removals for transaction commit.
	 */
    PersistentDatabase_DirIterateInit();
    while (PersistentDatabase_DirIterateNext(
                                        &dbDirNode,
                                        &persistentState,
                                        &persistentTid,
                                        &persistentSerialNum))
    {
        if (dbDirNode.tablespace != tablespaceoid)
            continue;

		/*
		 * Database directory objects can linger in 'Drop Pending' state, etc,
		 * when the mirror is down and needs drop work.  So only pay attention
		 * to 'Created' objects.
		 */
        if (persistentState != PersistentFileSysState_Created)
            continue;

        MirroredFileSysObj_ScheduleDropDbDir(
                                        &dbDirNode,
                                        &persistentTid,
                                        persistentSerialNum);
    }

	/*
	 * Now schedule the tablespace directory removal.
	 */
	MirroredFileSysObj_ScheduleDropTablespaceDir(tablespaceoid);

	/*
	 * Note: because we checked that the tablespace was empty, there should be
	 * no need to worry about flushing shared buffers or free space map
	 * entries for relations in the tablespace.
	 *
	 * CHECK THIS, also check if the lock makes any sense in this context.
	 */

	/*
	 * Force synchronous commit, to minimize the window between removing the
	 * files on-disk and marking the transaction committed.  It's not great
	 * that there is any window at all, but definitely we don't want to make
	 * it larger than necessary.
	 */
	ForceSyncCommit();

	/*
	 * Allow MirroredFileSysObj_JustInTimeDbDirCreate again.
	 */
	LWLockRelease(TablespaceCreateLock);

	/* We keep the lock on the row in pg_tablespace until commit */
	heap_close(rel, NoLock);

	/* Note: no need for dispatch, that is handled in utility.c */
	return;
}
Example #7
0
/* ----------------------------------------------------------------
 *		ExecInitFunctionScan
 * ----------------------------------------------------------------
 */
FunctionScanState *
ExecInitFunctionScan(FunctionScan *node, EState *estate, int eflags)
{
	FunctionScanState *scanstate;
	Oid			funcrettype;
	TypeFuncClass functypclass;
	TupleDesc	tupdesc = NULL;

	/* check for unsupported flags */
	Assert(!(eflags & EXEC_FLAG_MARK));

	/*
	 * FunctionScan should not have any children.
	 */
	Assert(outerPlan(node) == NULL);
	Assert(innerPlan(node) == NULL);

	/*
	 * create new ScanState for node
	 */
	scanstate = makeNode(FunctionScanState);
	scanstate->ss.ps.plan = (Plan *) node;
	scanstate->ss.ps.state = estate;
	scanstate->eflags = eflags;

	/*
	 * Miscellaneous initialization
	 *
	 * create expression context for node
	 */
	ExecAssignExprContext(estate, &scanstate->ss.ps);

	/*
	 * tuple table initialization
	 */
	ExecInitResultTupleSlot(estate, &scanstate->ss.ps);
	ExecInitScanTupleSlot(estate, &scanstate->ss);

	/*
	 * initialize child expressions
	 */
	scanstate->ss.ps.targetlist = (List *)
		ExecInitExpr((Expr *) node->scan.plan.targetlist,
					 (PlanState *) scanstate);
	scanstate->ss.ps.qual = (List *)
		ExecInitExpr((Expr *) node->scan.plan.qual,
					 (PlanState *) scanstate);

	/*
	 * Now determine if the function returns a simple or composite type, and
	 * build an appropriate tupdesc.
	 */
	functypclass = get_expr_result_type(node->funcexpr,
										&funcrettype,
										&tupdesc);

	if (functypclass == TYPEFUNC_COMPOSITE)
	{
		/* Composite data type, e.g. a table's row type */
		Assert(tupdesc);
		/* Must copy it out of typcache for safety */
		tupdesc = CreateTupleDescCopy(tupdesc);
	}
	else if (functypclass == TYPEFUNC_SCALAR)
	{
		/* Base data type, i.e. scalar */
		char	   *attname = strVal(linitial(node->funccolnames));

		tupdesc = CreateTemplateTupleDesc(1, false);
		TupleDescInitEntry(tupdesc,
						   (AttrNumber) 1,
						   attname,
						   funcrettype,
						   -1,
						   0);
	}
	else if (functypclass == TYPEFUNC_RECORD)
	{
		tupdesc = BuildDescFromLists(node->funccolnames,
									 node->funccoltypes,
									 node->funccoltypmods);
	}
	else
	{
		/* crummy error message, but parser should have caught this */
		elog(ERROR, "function in FROM has unsupported return type");
	}

	/*
	 * For RECORD results, make sure a typmod has been assigned.  (The
	 * function should do this for itself, but let's cover things in case it
	 * doesn't.)
	 */
	BlessTupleDesc(tupdesc);

	scanstate->tupdesc = tupdesc;
	ExecAssignScanType(&scanstate->ss, tupdesc);

	/*
	 * Other node-specific setup
	 */
	scanstate->tuplestorestate = NULL;
	scanstate->funcexpr = ExecInitExpr((Expr *) node->funcexpr,
									   (PlanState *) scanstate);

	scanstate->ss.ps.ps_TupFromTlist = false;

	/*
	 * Initialize result tuple type and projection info.
	 */
	ExecAssignResultTypeFromTL(&scanstate->ss.ps);
	ExecAssignScanProjectionInfo(&scanstate->ss);

	return scanstate;
}
Example #8
0
void OTVariable::Serialize(OTString & strAppend,
						   bool bCalculatingID/*=false*/)
{
	// ---------------------------------------
	std::string str_access("");

	switch (m_Access) {
		case OTVariable::Var_Constant:		// This cannot be changed from inside the script.
			str_access = "constant";
			break;
		case OTVariable::Var_Persistent:	// This can be changed without notifying the parties.
			str_access = "persistent";
			break;
		case OTVariable::Var_Important:		// This cannot be changed without notifying the parties.
			str_access = "important";
			break;
		default:
			OTLog::Error("OTVariable::Serialize:  ERROR:  Bad variable type.\n");
			break;
	}
	// ---------------------------------------
	std::string str_type;

	switch (m_Type) {
		case OTVariable::Var_String:
		{
			str_type = "string";

			if ((false == bCalculatingID) && // we don't serialize the variable's value when calculating the
				(m_str_Value.size() > 0)) // owner OTScriptable's ID, since the value can change over time.
			{
				OTString strVal(m_str_Value.c_str());
				OTASCIIArmor ascVal(strVal);
				strAppend.Concatenate("<variable\n name=\"%s\"\n"
									  " value=\"%s\"\n"
									  " type=\"%s\"\n"
									  " access=\"%s\" >\n%s</variable>\n\n",
									  m_strName.Get(),
									  "exists",
									  str_type.c_str(),
									  str_access.c_str(),
									  ascVal.Get());
			}
			else
			{
				strAppend.Concatenate("<variable\n name=\"%s\"\n"
									  " value=\"%s\"\n"
									  " type=\"%s\"\n"
									  " access=\"%s\" />\n\n",
									  m_strName.Get(),
									  "none", // value
									  str_type.c_str(),
									  str_access.c_str());
			}
		}
			break;
		case OTVariable::Var_Integer:
			str_type = "integer";
			strAppend.Concatenate("<variable\n name=\"%s\"\n"
								  " value=\"%d\"\n"
								  " type=\"%s\"\n"
								  " access=\"%s\" />\n\n",
								  m_strName.Get(),
								  bCalculatingID ? 0 : m_nValue, // we don't serialize the variable's value when calculating the smart contract's ID.
								  str_type.c_str(), str_access.c_str());
			break;
		case OTVariable::Var_Bool:
			str_type = "bool";
			strAppend.Concatenate("<variable\n name=\"%s\"\n"
								  " value=\"%s\"\n"
								  " type=\"%s\"\n"
								  " access=\"%s\" />\n\n",
								  m_strName.Get(),
								  bCalculatingID ? "false" : (m_bValue ? "true" : "false"), // we don't serialize the variable's value when calculating the smart contract's ID.
								  str_type.c_str(), str_access.c_str());
			break;
		default:
			str_type = "ERROR_VARIABLE_TYPE";
			OTLog::Error("OTVariable::Serialize: Error, Wrong Type -- not serializing.\n");
			break;
	}
	// ---------------------------------------
}
Example #9
0
/*
 *	DefineFileSystem
 */
void
DefineFileSystem(List *name, List *parameters, Oid newOid, bool trusted)
{
	char	   *fsysName;
	Oid			fsysNamespace;
	AclResult	aclresult;
	List	   *funcNames[FSYS_FUNC_TOTALNUM];
	char	   *fsysLibFile = NULL;
	int			funcNum = 0;
	ListCell   *pl;
	Oid			fsysOid;

	/* Convert list of names to a name and namespace */
	fsysNamespace = QualifiedNameGetCreationNamespace(name, &fsysName);

	/* Check we have creation rights in target namespace */
	aclresult = pg_namespace_aclcheck(fsysNamespace, GetUserId(), ACL_CREATE);
	if (aclresult != ACLCHECK_OK)
		aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
					   get_namespace_name(fsysNamespace));

	for(int i = 0; i < FSYS_FUNC_TOTALNUM; i++)
		funcNames[i] = NIL;

	foreach(pl, parameters)
	{
		DefElem    *defel = (DefElem *) lfirst(pl);
		int funcType;

		if (pg_strcasecmp(defel->defname, fsysLibFileName) == 0)
		{
			if(fsysLibFile == NULL)
			{
				fsysLibFile = strVal(linitial(defGetQualifiedName(defel)));
			}
			else
			{
				ereport(ERROR,
						(errcode(ERRCODE_SYNTAX_ERROR),
						 errmsg("filesystem attribute \"%s\" duplicated",
								defel->defname)));
			}
			continue;
		}

		for(funcType = 0; funcType < FSYS_FUNC_TOTALNUM; funcType++)
		{
			if(pg_strcasecmp(defel->defname, fsys_func_type_to_name(funcType)) == 0)
				break;
		}
		if (funcType >= FSYS_FUNC_TOTALNUM)
			ereport(ERROR,
					(errcode(ERRCODE_SYNTAX_ERROR),
					 errmsg("filesystem attribute \"%s\" not recognized",
							defel->defname)));
		if(funcNames[funcType] == NIL)
			funcNames[funcType] = defGetQualifiedName(defel);
		else
			ereport(ERROR,
					(errcode(ERRCODE_SYNTAX_ERROR),
					 errmsg("filesystem function \"%s\" duplicated",
							defel->defname)));
		funcNum++;
	}
Example #10
0
void
parseHwParameters(List *parameterList, HoltWintersModel *specificModel) {
	ListCell				*cell;
	foreach(cell,parameterList) {
		AlgorithmParameter		*param = lfirst(cell);

		/* Seasonflag*/
		if(strcmp(param->key,"has_season") == 0) {
			if(IsA(&(param->value->val),Integer)) {
				specificModel->doseasonal = intVal(&param->value->val);
				specificModel->optflag[2]=specificModel->doseasonal;
			} else
				ereport(ERROR,
				        (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
				         errmsg("Parameter value has to be an Integer value"),
				         errposition(param->value->location)));
		} else if(strcmp(param->key,"has_trend") == 0) {
			if(IsA(&(param->value->val),Integer)) {
				specificModel->dotrend = intVal(&param->value->val);
				specificModel->optflag[1]=specificModel->dotrend;
			} else
				ereport(ERROR,
				        (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
				         errmsg("Parameter value has to be an Integer value"),
				         errposition(param->value->location)));
					
		} else if(strcmp(param->key,"seasontype") == 0) {
			if(IsA(&(param->value->val),Integer)) {
				specificModel->seasonType = intVal(&param->value->val);
			} else
				ereport(ERROR,
				        (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
				         errmsg("Parameter value has to be an Integer value"),
				         errposition(param->value->location)));
					
		} else if(strcmp(param->key,"alpha") == 0) {
			if(IsA(&(param->value->val),Float)) {
				specificModel->alpha = floatVal(&param->value->val);
				specificModel->optflag[0]=0;
			} else
				ereport(ERROR,
				        (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
				         errmsg("Parameter value has to be an float value"),
				         errposition(param->value->location)));
					
		}else if(strcmp(param->key,"beta") == 0) {
			if(IsA(&(param->value->val),Float)) {
				specificModel->beta = floatVal(&param->value->val);
				specificModel->optflag[1]=0;
				specificModel->dotrend=1;
			} else
				ereport(ERROR,
				        (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
				         errmsg("Parameter value has to be an float value"),
				         errposition(param->value->location)));
					
		}else if(strcmp(param->key,"gamma") == 0) {
			if(IsA(&(param->value->val),Float)) {
				specificModel->gamma = floatVal(&param->value->val);
				specificModel->optflag[2]=0;
				specificModel->doseasonal=1;
			} else
				ereport(ERROR,
				        (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
				         errmsg("Parameter value has to be an float value"),
				         errposition(param->value->location)));
					
		}else if(strcmp(param->key,"season") == 0) {
			if(IsA(&(param->value->val),Integer)) {
				specificModel->period = intVal(&param->value->val);
				specificModel->doseasonal = 1;
				specificModel->optflag[2]=specificModel->doseasonal;
			} else
				ereport(ERROR,
				        (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
				         errmsg("Parameter value has to be an Integer value"),
				         errposition(param->value->location)));
		}  else if(strcmp(param->key,"error") == 0) {
			if(IsA(&(param->value->val),String)) {
				specificModel->errorfunction = palloc0((strlen(strVal(&param->value->val))+1)*sizeof(char));
				strcpy(specificModel->errorfunction,strVal(&param->value->val));
			} else
				ereport(ERROR,
				        (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
				         errmsg("Parameter value has to be an String value"),
				         errposition(param->value->location)));
		} else
			ereport(WARNING,
			        (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
			         errmsg("Parameter not known"),
			         errposition(((A_Const *)param->value)->location)));
	}
Example #11
0
/*
 * Executes an ALTER OBJECT / OWNER TO statement.  Based on the object
 * type, the function appropriate to that type is executed.
 */
void
ExecAlterOwnerStmt(AlterOwnerStmt *stmt)
{
	Oid			newowner = get_role_oid(stmt->newowner, false);

	switch (stmt->objectType)
	{
		case OBJECT_AGGREGATE:
			AlterAggregateOwner(stmt->object, stmt->objarg, newowner);
			break;

		case OBJECT_CONVERSION:
			AlterConversionOwner(stmt->object, newowner);
			break;

		case OBJECT_DATABASE:
			AlterDatabaseOwner(strVal(linitial(stmt->object)), newowner);
			break;

		case OBJECT_FUNCTION:
			AlterFunctionOwner(stmt->object, stmt->objarg, newowner);
			break;

		case OBJECT_LANGUAGE:
			AlterLanguageOwner(strVal(linitial(stmt->object)), newowner);
			break;

		case OBJECT_LARGEOBJECT:
			LargeObjectAlterOwner(oidparse(linitial(stmt->object)), newowner);
			break;

		case OBJECT_OPERATOR:
			Assert(list_length(stmt->objarg) == 2);
			AlterOperatorOwner(stmt->object,
							   (TypeName *) linitial(stmt->objarg),
							   (TypeName *) lsecond(stmt->objarg),
							   newowner);
			break;

		case OBJECT_OPCLASS:
			AlterOpClassOwner(stmt->object, stmt->addname, newowner);
			break;

		case OBJECT_OPFAMILY:
			AlterOpFamilyOwner(stmt->object, stmt->addname, newowner);
			break;

		case OBJECT_SCHEMA:
			AlterSchemaOwner(strVal(linitial(stmt->object)), newowner);
			break;

		case OBJECT_TABLESPACE:
			AlterTableSpaceOwner(strVal(linitial(stmt->object)), newowner);
			break;

		case OBJECT_TYPE:
		case OBJECT_DOMAIN:		/* same as TYPE */
			AlterTypeOwner(stmt->object, newowner);
			break;

		case OBJECT_TSDICTIONARY:
			AlterTSDictionaryOwner(stmt->object, newowner);
			break;

		case OBJECT_TSCONFIGURATION:
			AlterTSConfigurationOwner(stmt->object, newowner);
			break;

		case OBJECT_FDW:
			AlterForeignDataWrapperOwner(strVal(linitial(stmt->object)),
										 newowner);
			break;

		case OBJECT_FOREIGN_SERVER:
			AlterForeignServerOwner(strVal(linitial(stmt->object)), newowner);
			break;

		default:
			elog(ERROR, "unrecognized AlterOwnerStmt type: %d",
				 (int) stmt->objectType);
	}
}
Example #12
0
TEST(ExpandWalkerTests, All)
{
  ValCase cases[] = {
      {"substitute string", "foo=bar boo=${foo}", "boo", "bar", hit::Field::Kind::String},
      {"trailing space", "foo=bar boo=${foo} ", "boo", "bar", hit::Field::Kind::String},
      {"substute number", "foo=42 boo=${foo}", "boo", "42", hit::Field::Kind::Int},
      {"multiple replacements",
       "foo=42 boo='${foo} ${foo}'",
       "boo",
       "42 42",
       hit::Field::Kind::String},
      {"nested", "foo=bar [hello] boo='${foo}' []", "hello/boo", "bar", hit::Field::Kind::String},
      {"repl-header-before",
       "src=foo [src] bar='${src}' []",
       "src/bar",
       "foo",
       hit::Field::Kind::String},
      {"repl-header-missing", "[src] bar='${src}' []", "src/bar", "${src}", hit::Field::Kind::None},
      {"repl-header-shadow",
       "[src] bar='${src}' [] src=foo",
       "src/bar",
       "${src}",
       hit::Field::Kind::None},
      {"nested shadow",
       "foo=bar [hello] foo=baz boo='${foo}' []",
       "hello/boo",
       "baz",
       hit::Field::Kind::String},
  };

  for (size_t i = 0; i < sizeof(cases) / sizeof(ValCase); i++)
  {
    auto test = cases[i];
    hit::Node * root = nullptr;
    try
    {
      root = hit::parse("TEST", test.input);
      ExpandWalker exw("TEST");
      root->walk(&exw);
      if (exw.errors.size() > 0 && test.kind != hit::Field::Kind::None)
      {
        for (auto & err : exw.errors)
          FAIL() << "case " << i + 1 << " unexpected error: " << err << "\n";
        continue;
      }
      else if (exw.errors.size() == 0 && test.kind == hit::Field::Kind::None)
      {
        FAIL() << "case " << i + 1 << " missing expected error\n";
        continue;
      }
    }
    catch (std::exception & err)
    {
      FAIL() << "case " << i + 1 << " unexpected error: " << err.what() << "\n";
      continue;
    }

    auto n = root->find(test.key);
    if (!n)
    {
      FAIL() << "case " << i + 1 << " failed to find key '" << test.key << "'\n";
      continue;
    }
    if (n->strVal() != test.val)
    {
      FAIL() << "case " << i + 1 << " wrong value (key=" << test.key << "): got '" << n->strVal()
             << "', want '" << test.val << "'\n";
      continue;
    }

    auto f = dynamic_cast<hit::Field *>(n);
    if (!f)
      FAIL() << "case " << i + 1 << " node type is not NodeType::Field";
    else if (test.kind != hit::Field::Kind::None && f->kind() != test.kind)
      FAIL() << "case " << i + 1 << " wrong kind (key=" << test.key << "): got '"
             << strkind(f->kind()) << "', want '" << strkind(test.kind) << "'\n";
  }
}
Example #13
0
TEST(HitTests, ParseFields)
{
  ValCase cases[] = {
      // types
      {"int", "foo=42", "foo", "42", hit::Field::Kind::Int},
      {"float1", "foo=4.2", "foo", "4.2", hit::Field::Kind::Float},
      {"float2", "foo=.42", "foo", ".42", hit::Field::Kind::Float},
      {"float3", "foo=1e10", "foo", "1e10", hit::Field::Kind::Float},
      {"float4", "foo=e-23", "foo", "e-23", hit::Field::Kind::Float},
      {"float5", "foo=12.345e+67", "foo", "12.345e+67", hit::Field::Kind::Float},
      {"bool-true1", "foo=true", "foo", "true", hit::Field::Kind::Bool},
      {"bool-true2", "foo=yes", "foo", "yes", hit::Field::Kind::Bool},
      {"bool-true3", "foo=on", "foo", "on", hit::Field::Kind::Bool},
      {"bool-case1", "foo=TRUE", "foo", "TRUE", hit::Field::Kind::Bool},
      {"bool-case2", "foo=ON", "foo", "ON", hit::Field::Kind::Bool},
      {"bool-case3", "foo=YeS", "foo", "YeS", hit::Field::Kind::Bool},
      {"bool-false1", "foo=false", "foo", "false", hit::Field::Kind::Bool},
      {"bool-false2", "foo=no", "foo", "no", hit::Field::Kind::Bool},
      {"bool-false3", "foo=off", "foo", "off", hit::Field::Kind::Bool},
      {"string", "foo=bar", "foo", "bar", hit::Field::Kind::String},
      {"string-almost-float1", "foo=1e23.3", "foo", "1e23.3", hit::Field::Kind::String},
      {"string-almost-float2", "foo=1a23.3", "foo", "1a23.3", hit::Field::Kind::String},
      {"string-almost-float3", "foo=1.2.3", "foo", "1.2.3", hit::Field::Kind::String},
      {"string-almost-float4", "foo=1e2e3", "foo", "1e2e3", hit::Field::Kind::String},

      // quotes and escaping
      {"quotes", "foo='bar'", "foo", "bar", hit::Field::Kind::String},
      {"doublequotes", "foo=\"bar\"", "foo", "bar", hit::Field::Kind::String},
      {"quotes_quotes", "foo='\\'bar\\''", "foo", "'bar'", hit::Field::Kind::String},
      {"quotes_doublequotes", "foo='\"bar\"'", "foo", "\"bar\"", hit::Field::Kind::String},
      {"doublequotes_doublequotes",
       "foo=\"\\\"bar\\\"\"",
       "foo",
       "\"bar\"",
       hit::Field::Kind::String},

      // misc
      {"valid special field chars",
       "hello_./:<>-+world=foo",
       "hello_./:<>-+world",
       "foo",
       hit::Field::Kind::String},
      {"left-bracket-after-number", "[hello]foo=42[]", "hello/foo", "42", hit::Field::Kind::Int},
      {"ignore leading spaces 1", "foo=    bar", "foo", "bar", hit::Field::Kind::String},
      {"ignore leading spaces 2", "foo=     \t42", "foo", "42", hit::Field::Kind::Int},
      {"ignore trailing spaces", "foo=bar\t   ", "foo", "bar", hit::Field::Kind::String},
      {"ignore unknown escapes",
       "foo='hello \\my nam\\e is joe'",
       "foo",
       "hello \\my nam\\e is joe",
       hit::Field::Kind::String},
      {"no escaped newline",
       "foo='hello\\nworld'",
       "foo",
       "hello\\nworld",
       hit::Field::Kind::String},
      {"cosecutive string literal 1", "foo='bar''baz'", "foo", "barbaz", hit::Field::Kind::String},
      {"cosecutive string literal 2",
       "foo='bar'\n\n'baz'",
       "foo",
       "barbaz",
       hit::Field::Kind::String},
  };

  for (size_t i = 0; i < sizeof(cases) / sizeof(ValCase); i++)
  {
    auto test = cases[i];
    auto root = hit::parse("TEST", test.input);
    auto n = root->find(test.key);
    if (!n)
    {
      FAIL() << "case " << i + 1 << " (" << test.name << ") failed to find key '" << test.key
             << "'\n";
      continue;
    }
    if (n->strVal() != test.val)
    {
      FAIL() << "case " << i + 1 << " (" << test.name << ") wrong value (key=" << test.key
             << "): got '" << n->strVal() << "', want '" << test.val << "'\n";
      continue;
    }

    auto f = dynamic_cast<hit::Field *>(n);
    if (!f)
      FAIL() << "case " << i + 1 << " node type is not NodeType::Field";
    else if (f->kind() != test.kind)
      FAIL() << "case " << i + 1 << " wrong kind (key=" << test.key << "): got '"
             << strkind(f->kind()) << "', want '" << strkind(test.kind) << "'\n";
  }
}
Example #14
0
File: pg_enum.c Project: 50wu/gpdb
/*
 * EnumValuesCreate
 *		Create an entry in pg_enum for each of the supplied enum values.
 *
 * vals is a list of Value strings.
 */
void
EnumValuesCreate(Oid enumTypeOid, List *vals)
{
	Relation	pg_enum;
	TupleDesc	tupDesc;
	NameData	enumlabel;
	Oid		   *oids;
	int			i,
				n;
	Datum		values[Natts_pg_enum];
	bool		nulls[Natts_pg_enum];
	ListCell   *lc;
	HeapTuple	tup;

	n = list_length(vals);

	/*
	 * XXX we do not bother to check the list of values for duplicates --- if
	 * you have any, you'll get a less-than-friendly unique-index violation.
	 * Is it worth trying harder?
	 */

	pg_enum = heap_open(EnumRelationId, RowExclusiveLock);
	tupDesc = pg_enum->rd_att;

	/*
	 * Allocate oids.  While this method does not absolutely guarantee that we
	 * generate no duplicate oids (since we haven't entered each oid into the
	 * table before allocating the next), trouble could only occur if the oid
	 * counter wraps all the way around before we finish. Which seems
	 * unlikely.
	 */
	oids = (Oid *) palloc(n * sizeof(Oid));
	for (i = 0; i < n; i++)
	{
		/*
		 * In QE node, however, use the OIDs assigned by the master (they are delivered
		 * out-of-band, see oid_dispatch.c.
		 */
		if (Gp_role == GP_ROLE_EXECUTE)
			oids[i] = InvalidOid;
		else
			oids[i] = GetNewOid(pg_enum);
	}

	/* sort them, just in case counter wrapped from high to low */
	qsort(oids, n, sizeof(Oid), oid_cmp);

	/* and make the entries */
	memset(nulls, false, sizeof(nulls));

	i = 0;
	foreach(lc, vals)
	{
		char	   *lab = strVal(lfirst(lc));

		/*
		 * labels are stored in a name field, for easier syscache lookup, so
		 * check the length to make sure it's within range.
		 */
		if (strlen(lab) > (NAMEDATALEN - 1))
			ereport(ERROR,
					(errcode(ERRCODE_INVALID_NAME),
					 errmsg("invalid enum label \"%s\"", lab),
					 errdetail("Labels must be %d characters or less.",
							   NAMEDATALEN - 1)));

		values[Anum_pg_enum_enumtypid - 1] = ObjectIdGetDatum(enumTypeOid);
		namestrcpy(&enumlabel, lab);
		values[Anum_pg_enum_enumlabel - 1] = NameGetDatum(&enumlabel);

		tup = heap_form_tuple(tupDesc, values, nulls);
		HeapTupleSetOid(tup, oids[i]);

		simple_heap_insert(pg_enum, tup);
		CatalogUpdateIndexes(pg_enum, tup);
		heap_freetuple(tup);

		i++;
	}
Example #15
0
/*
 * Find an ObjectAddress for a type of object that is identified by an
 * unqualified name.
 */
static ObjectAddress
get_object_address_unqualified(ObjectType objtype, List *qualname)
{
	const char *name;
	ObjectAddress address;

	/*
	 * The types of names handled by this function are not permitted to be
	 * schema-qualified or catalog-qualified.
	 */
	if (list_length(qualname) != 1)
	{
		const char *msg;

		switch (objtype)
		{
			case OBJECT_DATABASE:
				msg = gettext_noop("database name cannot be qualified");
				break;
			case OBJECT_EXTENSION:
				msg = gettext_noop("extension name cannot be qualified");
				break;
			case OBJECT_TABLESPACE:
				msg = gettext_noop("tablespace name cannot be qualified");
				break;
			case OBJECT_ROLE:
				msg = gettext_noop("role name cannot be qualified");
				break;
			case OBJECT_SCHEMA:
				msg = gettext_noop("schema name cannot be qualified");
				break;
			case OBJECT_LANGUAGE:
				msg = gettext_noop("language name cannot be qualified");
				break;
			case OBJECT_FDW:
				msg = gettext_noop("foreign-data wrapper name cannot be qualified");
				break;
			case OBJECT_FOREIGN_SERVER:
				msg = gettext_noop("server name cannot be qualified");
				break;
			default:
				elog(ERROR, "unrecognized objtype: %d", (int) objtype);
				msg = NULL;			/* placate compiler */
		}
		ereport(ERROR,
				(errcode(ERRCODE_SYNTAX_ERROR),
				 errmsg("%s", _(msg))));
	}

	/* Format is valid, extract the actual name. */
	name = strVal(linitial(qualname));

	/* Translate name to OID. */
	switch (objtype)
	{
		case OBJECT_DATABASE:
			address.classId = DatabaseRelationId;
			address.objectId = get_database_oid(name, false);
			address.objectSubId = 0;
			break;
		case OBJECT_EXTENSION:
			address.classId = ExtensionRelationId;
			address.objectId = get_extension_oid(name, false);
			address.objectSubId = 0;
			break;
		case OBJECT_TABLESPACE:
			address.classId = TableSpaceRelationId;
			address.objectId = get_tablespace_oid(name, false);
			address.objectSubId = 0;
			break;
		case OBJECT_ROLE:
			address.classId = AuthIdRelationId;
			address.objectId = get_role_oid(name, false);
			address.objectSubId = 0;
			break;
		case OBJECT_SCHEMA:
			address.classId = NamespaceRelationId;
			address.objectId = get_namespace_oid(name, false);
			address.objectSubId = 0;
			break;
		case OBJECT_LANGUAGE:
			address.classId = LanguageRelationId;
			address.objectId = get_language_oid(name, false);
			address.objectSubId = 0;
			break;
		case OBJECT_FDW:
			address.classId = ForeignDataWrapperRelationId;
			address.objectId = get_foreign_data_wrapper_oid(name, false);
			address.objectSubId = 0;
			break;
		case OBJECT_FOREIGN_SERVER:
			address.classId = ForeignServerRelationId;
			address.objectId = get_foreign_server_oid(name, false);
			address.objectSubId = 0;
			break;
		default:
			elog(ERROR, "unrecognized objtype: %d", (int) objtype);
			/* placate compiler, which doesn't know elog won't return */
			address.classId = InvalidOid;
			address.objectId = InvalidOid;
			address.objectSubId = 0;
	}

	return address;
}
/*
 * EnumValuesCreate
 *		Create an entry in pg_enum for each of the supplied enum values.
 *
 * vals is a list of Value strings.
 */
void
EnumValuesCreate(Oid enumTypeOid, List *vals,
				 Oid binary_upgrade_next_pg_enum_oid)
{
	Relation	pg_enum;
	TupleDesc	tupDesc;
	NameData	enumlabel;
	Oid		   *oids;
	int			elemno,
				num_elems;
	Datum		values[Natts_pg_enum];
	bool		nulls[Natts_pg_enum];
	ListCell   *lc;
	HeapTuple	tup;

	num_elems = list_length(vals);

	/*
	 * XXX we do not bother to check the list of values for duplicates --- if
	 * you have any, you'll get a less-than-friendly unique-index violation.
	 * Is it worth trying harder?
	 */

	pg_enum = heap_open(EnumRelationId, RowExclusiveLock);
	tupDesc = pg_enum->rd_att;

	/*
	 * Allocate oids
	 */
	oids = (Oid *) palloc(num_elems * sizeof(Oid));
	if (OidIsValid(binary_upgrade_next_pg_enum_oid))
	{
		if (num_elems != 1)
			ereport(ERROR,
					(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
					 errmsg("EnumValuesCreate() can only set a single OID")));
		oids[0] = binary_upgrade_next_pg_enum_oid;
		binary_upgrade_next_pg_enum_oid = InvalidOid;
	}
	else
	{
		/*
		 * While this method does not absolutely guarantee that we generate no
		 * duplicate oids (since we haven't entered each oid into the table
		 * before allocating the next), trouble could only occur if the oid
		 * counter wraps all the way around before we finish. Which seems
		 * unlikely.
		 */
		for (elemno = 0; elemno < num_elems; elemno++)
		{
			/*
			 * The pg_enum.oid is stored in user tables.  This oid must be
			 * preserved by binary upgrades.
			 */
			oids[elemno] = GetNewOid(pg_enum);
		}
		/* sort them, just in case counter wrapped from high to low */
		qsort(oids, num_elems, sizeof(Oid), oid_cmp);
	}

	/* and make the entries */
	memset(nulls, false, sizeof(nulls));

	elemno = 0;
	foreach(lc, vals)
	{
		char	   *lab = strVal(lfirst(lc));

		/*
		 * labels are stored in a name field, for easier syscache lookup, so
		 * check the length to make sure it's within range.
		 */
		if (strlen(lab) > (NAMEDATALEN - 1))
			ereport(ERROR,
					(errcode(ERRCODE_INVALID_NAME),
					 errmsg("invalid enum label \"%s\"", lab),
					 errdetail("Labels must be %d characters or less.",
							   NAMEDATALEN - 1)));

		values[Anum_pg_enum_enumtypid - 1] = ObjectIdGetDatum(enumTypeOid);
		namestrcpy(&enumlabel, lab);
		values[Anum_pg_enum_enumlabel - 1] = NameGetDatum(&enumlabel);

		tup = heap_form_tuple(tupDesc, values, nulls);
		HeapTupleSetOid(tup, oids[elemno]);

		simple_heap_insert(pg_enum, tup);
		CatalogUpdateIndexes(pg_enum, tup);
		heap_freetuple(tup);

		elemno++;
	}
Example #17
0
/*
 * Find object address for an object that is attached to a relation.
 *
 * Note that we take only an AccessShareLock on the relation.  We need not
 * pass down the LOCKMODE from get_object_address(), because that is the lock
 * mode for the object itself, not the relation to which it is attached.
 */
static ObjectAddress
get_object_address_relobject(ObjectType objtype, List *objname, Relation *relp)
{
	ObjectAddress address;
	Relation	relation = NULL;
	int			nnames;
	const char *depname;

	/* Extract name of dependent object. */
	depname = strVal(lfirst(list_tail(objname)));

	/* Separate relation name from dependent object name. */
	nnames = list_length(objname);
	if (nnames < 2)
	{
		Oid		reloid;

		/*
		 * For compatibility with very old releases, we sometimes allow users
		 * to attempt to specify a rule without mentioning the relation name.
		 * If there's only rule by that name in the entire database, this will
		 * work.  But objects other than rules don't get this special
		 * treatment.
		 */
		if (objtype != OBJECT_RULE)
			elog(ERROR, "must specify relation and object name");
		address.classId = RewriteRelationId;
		address.objectId = get_rewrite_oid_without_relid(depname, &reloid);
		address.objectSubId = 0;
		relation = heap_open(reloid, AccessShareLock);
	}
	else
	{
		List	   *relname;
		Oid			reloid;

		/* Extract relation name and open relation. */
		relname = list_truncate(list_copy(objname), nnames - 1);
		relation = heap_openrv(makeRangeVarFromNameList(relname),
							   AccessShareLock);
		reloid = RelationGetRelid(relation);

		switch (objtype)
		{
			case OBJECT_RULE:
				address.classId = RewriteRelationId;
				address.objectId = get_rewrite_oid(reloid, depname, false);
				address.objectSubId = 0;
				break;
			case OBJECT_TRIGGER:
				address.classId = TriggerRelationId;
				address.objectId = get_trigger_oid(reloid, depname, false);
				address.objectSubId = 0;
				break;
			case OBJECT_CONSTRAINT:
				address.classId = ConstraintRelationId;
				address.objectId = get_constraint_oid(reloid, depname, false);
				address.objectSubId = 0;
				break;
			default:
				elog(ERROR, "unrecognized objtype: %d", (int) objtype);
				/* placate compiler, which doesn't know elog won't return */
				address.classId = InvalidOid;
				address.objectId = InvalidOid;
				address.objectSubId = 0;
		}
	}

	/* Done. */
	*relp = relation;
	return address;
}
Example #18
0
/*
 * Walker function to find a function call which is supposed to write
 * database.
 */
static bool
function_call_walker(Node *node, void *context)
{
	SelectContext *ctx = (SelectContext *) context;

	if (node == NULL)
		return false;

	if (IsA(node, FuncCall))
	{
		FuncCall   *fcall = (FuncCall *) node;
		char	   *fname;
		int			length = list_length(fcall->funcname);

		if (length > 0)
		{
			if (length == 1)	/* no schema qualification? */
			{
				fname = strVal(linitial(fcall->funcname));
			}
			else
			{
				fname = strVal(lsecond(fcall->funcname));	/* with schema
															 * qualification */
			}

			ereport(DEBUG1,
					(errmsg("function call walker, function name: \"%s\"", fname)));

			if (ctx->pg_terminate_backend_pid == 0 && strcmp("pg_terminate_backend", fname) == 0)
			{
				if (list_length(fcall->args) == 1)
				{
					Node	   *arg = linitial(fcall->args);

					if (IsA(arg, A_Const) &&
						((A_Const *) arg)->val.type == T_Integer)
					{
						ctx->pg_terminate_backend_pid = ((A_Const *) arg)->val.val.ival;
						ereport(DEBUG1,
								(errmsg("pg_terminate_backend pid = %d", ctx->pg_terminate_backend_pid)));
					}
				}
			}

			/*
			 * Check white list if any.
			 */
			if (pool_config->num_white_function_list > 0)
			{
				/* Search function in the white list regex patterns */
				if (pattern_compare(fname, WHITELIST, "white_function_list") == 1)
				{
					/*
					 * If the function is found in the white list, we can
					 * ignore it
					 */
					return raw_expression_tree_walker(node, function_call_walker, context);
				}

				/*
				 * Since the function was not found in white list, we have
				 * found a writing function.
				 */
				ctx->has_function_call = true;
				return false;
			}

			/*
			 * Check black list if any.
			 */
			if (pool_config->num_black_function_list > 0)
			{
				/* Search function in the black list regex patterns */
				if (pattern_compare(fname, BLACKLIST, "black_function_list") == 1)
				{
					/* Found. */
					ctx->has_function_call = true;
					return false;
				}
			}
		}
	}
	return raw_expression_tree_walker(node, function_call_walker, context);
}
Example #19
0
/*
 * CommentObject --
 *
 * This routine is used to add the associated comment into
 * pg_description for the object specified by the given SQL command.
 */
void
CommentObject(CommentStmt *stmt)
{
	ObjectAddress	address;
	Relation		relation;

	/*
	 * When loading a dump, we may see a COMMENT ON DATABASE for the old name
	 * of the database.  Erroring out would prevent pg_restore from completing
	 * (which is really pg_restore's fault, but for now we will work around
	 * the problem here).  Consensus is that the best fix is to treat wrong
	 * database name as a WARNING not an ERROR; hence, the following special
	 * case.  (If the length of stmt->objname is not 1, get_object_address will
	 * throw an error below; that's OK.)
	 */
	if (stmt->objtype == OBJECT_DATABASE && list_length(stmt->objname) == 1)
	{
		char   *database = strVal(linitial(stmt->objname));
		if (!OidIsValid(get_database_oid(database, true)))
		{
			ereport(WARNING,
					(errcode(ERRCODE_UNDEFINED_DATABASE),
					 errmsg("database \"%s\" does not exist", database)));
			return;
		}
	}

	/*
	 * Translate the parser representation which identifies this object into
	 * an ObjectAddress. get_object_address() will throw an error if the
	 * object does not exist, and will also acquire a lock on the target
     * to guard against concurrent DROP operations.
	 */
	address = get_object_address(stmt->objtype, stmt->objname, stmt->objargs,
								 &relation, ShareUpdateExclusiveLock);

	/* Privilege and integrity checks. */
	switch (stmt->objtype)
	{
		case OBJECT_INDEX:
		case OBJECT_SEQUENCE:
		case OBJECT_TABLE:
		case OBJECT_VIEW:
			if (!pg_class_ownercheck(RelationGetRelid(relation), GetUserId()))
				aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
							   RelationGetRelationName(relation));
			break;
		case OBJECT_COLUMN:
			CheckAttributeComment(relation);
			break;
		case OBJECT_DATABASE:
			if (!pg_database_ownercheck(address.objectId, GetUserId()))
				aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_DATABASE,
							   strVal(linitial(stmt->objname)));
			break;
		case OBJECT_TYPE:
			if (!pg_type_ownercheck(address.objectId, GetUserId()))
				aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TYPE,
							   format_type_be(address.objectId));
			break;
		case OBJECT_AGGREGATE:
		case OBJECT_FUNCTION:
			if (!pg_proc_ownercheck(address.objectId, GetUserId()))
				aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_PROC,
							   NameListToString(stmt->objname));
			break;
		case OBJECT_OPERATOR:
			if (!pg_oper_ownercheck(address.objectId, GetUserId()))
				aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_OPER,
							   NameListToString(stmt->objname));
			break;
		case OBJECT_RULE:
		case OBJECT_TRIGGER:
		case OBJECT_CONSTRAINT:
			if (!pg_class_ownercheck(RelationGetRelid(relation), GetUserId()))
				aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
							   RelationGetRelationName(relation));
			break;
		case OBJECT_SCHEMA:
			if (!pg_namespace_ownercheck(address.objectId, GetUserId()))
				aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_NAMESPACE,
							   strVal(linitial(stmt->objname)));
			break;
		case OBJECT_CONVERSION:
			if (!pg_conversion_ownercheck(address.objectId, GetUserId()))
				aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CONVERSION,
							   NameListToString(stmt->objname));
			break;
		case OBJECT_LANGUAGE:
			if (!superuser())
				ereport(ERROR,
						(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
					 errmsg("must be superuser to comment on procedural language")));
			break;
		case OBJECT_OPCLASS:
			if (!pg_opclass_ownercheck(address.objectId, GetUserId()))
				aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_OPCLASS,
							   NameListToString(stmt->objname));
			break;
		case OBJECT_OPFAMILY:
			if (!pg_opfamily_ownercheck(address.objectId, GetUserId()))
				aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_OPFAMILY,
							   NameListToString(stmt->objname));
			break;
		case OBJECT_LARGEOBJECT:
			if (!lo_compat_privileges &&
				!pg_largeobject_ownercheck(address.objectId, GetUserId()))
				ereport(ERROR,
						(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
						 errmsg("must be owner of large object %u",
							address.objectId)));
			break;
		case OBJECT_CAST:
			CheckCastComment(stmt->objname, stmt->objargs);
			break;
		case OBJECT_TABLESPACE:
			if (!pg_tablespace_ownercheck(address.objectId, GetUserId()))
				aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TABLESPACE,
							   strVal(linitial(stmt->objname)));
			break;
		case OBJECT_ROLE:
			if (!has_privs_of_role(GetUserId(), address.objectId))
				ereport(ERROR,
						(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
				  errmsg("must be member of role \"%s\" to comment upon it",
						 strVal(linitial(stmt->objname)))));
			break;
		case OBJECT_TSPARSER:
			if (!superuser())
				ereport(ERROR,
						(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
					  errmsg("must be superuser to comment on text search parser")));
			break;
		case OBJECT_TSDICTIONARY:
			if (!pg_ts_dict_ownercheck(address.objectId, GetUserId()))
				aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TSDICTIONARY,
							   NameListToString(stmt->objname));
			break;
		case OBJECT_TSTEMPLATE:
			if (!superuser())
				ereport(ERROR,
						(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
					errmsg("must be superuser to comment on text search template")));
			break;
		case OBJECT_TSCONFIGURATION:
			if (!pg_ts_config_ownercheck(address.objectId, GetUserId()))
				aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TSCONFIGURATION,
							   NameListToString(stmt->objname));
			break;
		default:
			elog(ERROR, "unrecognized object type: %d",
				 (int) stmt->objtype);
	}

	/*
	 * Databases, tablespaces, and roles are cluster-wide objects, so any
	 * comments on those objects are recorded in the shared pg_shdescription
	 * catalog.  Comments on all other objects are recorded in pg_description.
	 */
	if (stmt->objtype == OBJECT_DATABASE || stmt->objtype == OBJECT_TABLESPACE
		|| stmt->objtype == OBJECT_ROLE)
		CreateSharedComments(address.objectId, address.classId, stmt->comment);
	else
		CreateComments(address.objectId, address.classId, address.objectSubId,
					   stmt->comment);

	/*
	 * If get_object_address() opened the relation for us, we close it to keep
	 * the reference count correct - but we retain any locks acquired by
	 * get_object_address() until commit time, to guard against concurrent
	 * activity.
	 */
	if (relation != NULL)
		relation_close(relation, NoLock);
}
Example #20
0
/*
 * Copied from src/backend/commands/indexcmds.c, not exported.
 * Resolve possibly-defaulted operator class specification
 */
Oid
GetIndexOpClass(List *opclass, Oid attrType,
				char *accessMethodName, Oid accessMethodId)
{
	char	   *schemaname;
	char	   *opcname;
	HeapTuple	tuple;
	Oid			opClassId,
				opInputType;

	/*
	 * Release 7.0 removed network_ops, timespan_ops, and datetime_ops, so we
	 * ignore those opclass names so the default *_ops is used.  This can be
	 * removed in some later release.  bjm 2000/02/07
	 *
	 * Release 7.1 removes lztext_ops, so suppress that too for a while.  tgl
	 * 2000/07/30
	 *
	 * Release 7.2 renames timestamp_ops to timestamptz_ops, so suppress that
	 * too for awhile.  I'm starting to think we need a better approach. tgl
	 * 2000/10/01
	 *
	 * Release 8.0 removes bigbox_ops (which was dead code for a long while
	 * anyway).  tgl 2003/11/11
	 */
	if (list_length(opclass) == 1)
	{
		char	   *claname = strVal(linitial(opclass));

		if (strcmp(claname, "network_ops") == 0 ||
			strcmp(claname, "timespan_ops") == 0 ||
			strcmp(claname, "datetime_ops") == 0 ||
			strcmp(claname, "lztext_ops") == 0 ||
			strcmp(claname, "timestamp_ops") == 0 ||
			strcmp(claname, "bigbox_ops") == 0)
			opclass = NIL;
	}

	if (opclass == NIL)
	{
		/* no operator class specified, so find the default */
		opClassId = GetDefaultOpClass(attrType, accessMethodId);
		if (!OidIsValid(opClassId))
			ereport(ERROR,
					(errcode(ERRCODE_UNDEFINED_OBJECT),
					 errmsg("data type %s has no default operator class for access method \"%s\"",
							format_type_be(attrType), accessMethodName),
					 errhint("You must specify an operator class for the index or define a default operator class for the data type.")));
		return opClassId;
	}

	/*
	 * Specific opclass name given, so look up the opclass.
	 */

	/* deconstruct the name list */
	DeconstructQualifiedName(opclass, &schemaname, &opcname);

	if (schemaname)
	{
		/* Look in specific schema only */
		Oid			namespaceId;

#if PG_VERSION_NUM >= 90300
		namespaceId = LookupExplicitNamespace(schemaname, false);
#else
		namespaceId = LookupExplicitNamespace(schemaname);
#endif
		tuple = SearchSysCache3(CLAAMNAMENSP,
								ObjectIdGetDatum(accessMethodId),
								PointerGetDatum(opcname),
								ObjectIdGetDatum(namespaceId));
	}
	else
	{
		/* Unqualified opclass name, so search the search path */
		opClassId = OpclassnameGetOpcid(accessMethodId, opcname);
		if (!OidIsValid(opClassId))
			ereport(ERROR,
					(errcode(ERRCODE_UNDEFINED_OBJECT),
					 errmsg("operator class \"%s\" does not exist for access method \"%s\"",
							opcname, accessMethodName)));
		tuple = SearchSysCache1(CLAOID, ObjectIdGetDatum(opClassId));
	}

	if (!HeapTupleIsValid(tuple))
	{
		ereport(ERROR,
				(errcode(ERRCODE_UNDEFINED_OBJECT),
				 errmsg("operator class \"%s\" does not exist for access method \"%s\"",
						NameListToString(opclass), accessMethodName)));
	}

	/*
	 * Verify that the index operator class accepts this datatype.  Note we
	 * will accept binary compatibility.
	 */
	opClassId = HeapTupleGetOid(tuple);
	opInputType = ((Form_pg_opclass) GETSTRUCT(tuple))->opcintype;

	if (!IsBinaryCoercible(attrType, opInputType))
		ereport(ERROR,
				(errcode(ERRCODE_DATATYPE_MISMATCH),
				 errmsg("operator class \"%s\" does not accept data type %s",
					  NameListToString(opclass), format_type_be(attrType))));

	ReleaseSysCache(tuple);

	return opClassId;
}
Example #21
0
/*
 * Executes an ALTER OBJECT / OWNER TO statement.  Based on the object
 * type, the function appropriate to that type is executed.
 */
void
ExecAlterOwnerStmt(AlterOwnerStmt *stmt)
{
	Oid			newowner = get_roleid_checked(stmt->newowner);

	switch (stmt->objectType)
	{
		case OBJECT_AGGREGATE:
			AlterAggregateOwner(stmt->object, stmt->objarg, newowner);
			break;

		case OBJECT_CONVERSION:
			AlterConversionOwner(stmt->object, newowner);
			break;

		case OBJECT_DATABASE:
			AlterDatabaseOwner(strVal(linitial(stmt->object)), newowner);
			break;

		case OBJECT_FUNCTION:
			AlterFunctionOwner(stmt->object, stmt->objarg, newowner);
			break;

		case OBJECT_OPERATOR:
			Assert(list_length(stmt->objarg) == 2);
			AlterOperatorOwner(stmt->object,
							   (TypeName *) linitial(stmt->objarg),
							   (TypeName *) lsecond(stmt->objarg),
							   newowner);
			break;

		case OBJECT_OPCLASS:
			AlterOpClassOwner(stmt->object, stmt->addname, newowner);
			break;

		case OBJECT_OPFAMILY:
			AlterOpFamilyOwner(stmt->object, stmt->addname, newowner);
			break;

		case OBJECT_SCHEMA:
			AlterSchemaOwner(strVal(linitial(stmt->object)), newowner);
			break;

		case OBJECT_TABLESPACE:
			AlterTableSpaceOwner(strVal(linitial(stmt->object)), newowner);
			break;

		case OBJECT_FILESPACE:
			AlterFileSpaceOwner(stmt->object, newowner);
			break;

		case OBJECT_TYPE:
		case OBJECT_DOMAIN:		/* same as TYPE */
			AlterTypeOwner(stmt->object, newowner);
			break;
		
		case OBJECT_EXTPROTOCOL:
			AlterExtProtocolOwner(strVal(linitial(stmt->object)), newowner);
			break;
			
		default:
			elog(ERROR, "unrecognized AlterOwnerStmt type: %d",
				 (int) stmt->objectType);
	}
	if (Gp_role == GP_ROLE_DISPATCH)
	{
		CdbDispatchUtilityStatement((Node *) stmt, "ExecAlterOwnerStmt");
	}
}
Example #22
0
/*
 *	Parse a function call
 *
 *	For historical reasons, Postgres tries to treat the notations tab.col
 *	and col(tab) as equivalent: if a single-argument function call has an
 *	argument of complex type and the (unqualified) function name matches
 *	any attribute of the type, we take it as a column projection.  Conversely
 *	a function of a single complex-type argument can be written like a
 *	column reference, allowing functions to act like computed columns.
 *
 *	Hence, both cases come through here.  The is_column parameter tells us
 *	which syntactic construct is actually being dealt with, but this is
 *	intended to be used only to deliver an appropriate error message,
 *	not to affect the semantics.  When is_column is true, we should have
 *	a single argument (the putative table), unqualified function name
 *	equal to the column name, and no aggregate or variadic decoration.
 *
 *	The argument expressions (in fargs) must have been transformed already.
 */
Node *
ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs,
				  bool agg_star, bool agg_distinct, bool func_variadic,
				  WindowDef *over, bool is_column, int location)
{
	Oid			rettype;
	Oid			funcid;
	ListCell   *l;
	ListCell   *nextl;
	Node	   *first_arg = NULL;
	int			nargs;
	int			nargsplusdefs;
	Oid			actual_arg_types[FUNC_MAX_ARGS];
	Oid		   *declared_arg_types;
	List	   *argdefaults;
	Node	   *retval;
	bool		retset;
	int			nvargs;
	FuncDetailCode fdresult;

	/*
	 * Most of the rest of the parser just assumes that functions do not have
	 * more than FUNC_MAX_ARGS parameters.	We have to test here to protect
	 * against array overruns, etc.  Of course, this may not be a function,
	 * but the test doesn't hurt.
	 */
	if (list_length(fargs) > FUNC_MAX_ARGS)
		ereport(ERROR,
				(errcode(ERRCODE_TOO_MANY_ARGUMENTS),
			 errmsg_plural("cannot pass more than %d argument to a function",
						   "cannot pass more than %d arguments to a function",
						   FUNC_MAX_ARGS,
						   FUNC_MAX_ARGS),
				 parser_errposition(pstate, location)));

	/*
	 * Extract arg type info in preparation for function lookup.
	 *
	 * If any arguments are Param markers of type VOID, we discard them from
	 * the parameter list.	This is a hack to allow the JDBC driver to not
	 * have to distinguish "input" and "output" parameter symbols while
	 * parsing function-call constructs.  We can't use foreach() because we
	 * may modify the list ...
	 */
	nargs = 0;
	for (l = list_head(fargs); l != NULL; l = nextl)
	{
		Node	   *arg = lfirst(l);
		Oid			argtype = exprType(arg);

		nextl = lnext(l);

		if (argtype == VOIDOID && IsA(arg, Param) &&!is_column)
		{
			fargs = list_delete_ptr(fargs, arg);
			continue;
		}

		actual_arg_types[nargs++] = argtype;
	}

	if (fargs)
	{
		first_arg = linitial(fargs);
		Assert(first_arg != NULL);
	}

	/*
	 * Check for column projection: if function has one argument, and that
	 * argument is of complex type, and function name is not qualified, then
	 * the "function call" could be a projection.  We also check that there
	 * wasn't any aggregate or variadic decoration.
	 */
	if (nargs == 1 && !agg_star && !agg_distinct && over == NULL &&
		!func_variadic && list_length(funcname) == 1)
	{
		Oid			argtype = actual_arg_types[0];

		if (argtype == RECORDOID || ISCOMPLEX(argtype))
		{
			retval = ParseComplexProjection(pstate,
											strVal(linitial(funcname)),
											first_arg,
											location);
			if (retval)
				return retval;

			/*
			 * If ParseComplexProjection doesn't recognize it as a projection,
			 * just press on.
			 */
		}
	}

	/*
	 * Okay, it's not a column projection, so it must really be a function.
	 * func_get_detail looks up the function in the catalogs, does
	 * disambiguation for polymorphic functions, handles inheritance, and
	 * returns the funcid and type and set or singleton status of the
	 * function's return value.  It also returns the true argument types to
	 * the function.  In the case of a variadic function call, the reported
	 * "true" types aren't really what is in pg_proc: the variadic argument is
	 * replaced by a suitable number of copies of its element type.  We'll fix
	 * it up below.  We may also have to deal with default arguments.
	 */
	fdresult = func_get_detail(funcname, fargs, nargs, actual_arg_types,
							   !func_variadic, true,
							   &funcid, &rettype, &retset, &nvargs,
							   &declared_arg_types, &argdefaults);
	if (fdresult == FUNCDETAIL_COERCION)
	{
		/*
		 * We interpreted it as a type coercion. coerce_type can handle these
		 * cases, so why duplicate code...
		 */
		return coerce_type(pstate, linitial(fargs),
						   actual_arg_types[0], rettype, -1,
						   COERCION_EXPLICIT, COERCE_EXPLICIT_CALL, location);
	}
	else if (fdresult == FUNCDETAIL_NORMAL)
	{
		/*
		 * Normal function found; was there anything indicating it must be an
		 * aggregate?
		 */
		if (agg_star)
			ereport(ERROR,
					(errcode(ERRCODE_WRONG_OBJECT_TYPE),
			   errmsg("%s(*) specified, but %s is not an aggregate function",
					  NameListToString(funcname),
					  NameListToString(funcname)),
					 parser_errposition(pstate, location)));
		if (agg_distinct)
			ereport(ERROR,
					(errcode(ERRCODE_WRONG_OBJECT_TYPE),
			errmsg("DISTINCT specified, but %s is not an aggregate function",
				   NameListToString(funcname)),
					 parser_errposition(pstate, location)));
		if (over)
			ereport(ERROR,
					(errcode(ERRCODE_WRONG_OBJECT_TYPE),
					 errmsg("OVER specified, but %s is not a window function nor an aggregate function",
							NameListToString(funcname)),
					 parser_errposition(pstate, location)));
	}
	else if (!(fdresult == FUNCDETAIL_AGGREGATE ||
			   fdresult == FUNCDETAIL_WINDOWFUNC))
	{
		/*
		 * Oops.  Time to die.
		 *
		 * If we are dealing with the attribute notation rel.function, give an
		 * error message that is appropriate for that case.
		 */
		if (is_column)
		{
			Assert(nargs == 1);
			Assert(list_length(funcname) == 1);
			unknown_attribute(pstate, first_arg, strVal(linitial(funcname)),
							  location);
		}

		/*
		 * Else generate a detailed complaint for a function
		 */
		if (fdresult == FUNCDETAIL_MULTIPLE)
			ereport(ERROR,
					(errcode(ERRCODE_AMBIGUOUS_FUNCTION),
					 errmsg("function %s is not unique",
							func_signature_string(funcname, nargs,
												  actual_arg_types)),
					 errhint("Could not choose a best candidate function. "
							 "You might need to add explicit type casts."),
					 parser_errposition(pstate, location)));
		else
			ereport(ERROR,
					(errcode(ERRCODE_UNDEFINED_FUNCTION),
					 errmsg("function %s does not exist",
							func_signature_string(funcname, nargs,
												  actual_arg_types)),
			errhint("No function matches the given name and argument types. "
					"You might need to add explicit type casts."),
					 parser_errposition(pstate, location)));
	}

	/*
	 * If there are default arguments, we have to include their types in
	 * actual_arg_types for the purpose of checking generic type consistency.
	 * However, we do NOT put them into the generated parse node, because
	 * their actual values might change before the query gets run.	The
	 * planner has to insert the up-to-date values at plan time.
	 */
	nargsplusdefs = nargs;
	foreach(l, argdefaults)
	{
		Node	   *expr = (Node *) lfirst(l);

		/* probably shouldn't happen ... */
		if (nargsplusdefs >= FUNC_MAX_ARGS)
			ereport(ERROR,
					(errcode(ERRCODE_TOO_MANY_ARGUMENTS),
			 errmsg_plural("cannot pass more than %d argument to a function",
						   "cannot pass more than %d arguments to a function",
						   FUNC_MAX_ARGS,
						   FUNC_MAX_ARGS),
					 parser_errposition(pstate, location)));

		actual_arg_types[nargsplusdefs++] = exprType(expr);
	}
Example #23
0
/*
 * TypeGetTupleDesc
 *
 * Given a type Oid, build a TupleDesc.  (In most cases you should be
 * using get_call_result_type or one of its siblings instead of this
 * routine, so that you can handle OUT parameters, RECORD result type,
 * and polymorphic results.)
 *
 * If the type is composite, *and* a colaliases List is provided, *and*
 * the List is of natts length, use the aliases instead of the relation
 * attnames.  (NB: this usage is deprecated since it may result in
 * creation of unnecessary transient record types.)
 *
 * If the type is a base type, a single item alias List is required.
 */
TupleDesc
TypeGetTupleDesc(Oid typeoid, List *colaliases)
{
	TypeFuncClass functypclass = get_type_func_class(typeoid);
	TupleDesc	tupdesc = NULL;

	/*
	 * Build a suitable tupledesc representing the output rows
	 */
	if (functypclass == TYPEFUNC_COMPOSITE)
	{
		/* Composite data type, e.g. a table's row type */
		tupdesc = lookup_rowtype_tupdesc_copy(typeoid, -1);

		if (colaliases != NIL)
		{
			int			natts = tupdesc->natts;
			int			varattno;

			/* does the list length match the number of attributes? */
			if (list_length(colaliases) != natts)
				ereport(ERROR,
						(errcode(ERRCODE_DATATYPE_MISMATCH),
						 errmsg("number of aliases does not match number of columns")));

			/* OK, use the aliases instead */
			for (varattno = 0; varattno < natts; varattno++)
			{
				char	   *label = strVal(list_nth(colaliases, varattno));

				if (label != NULL)
					namestrcpy(&(tupdesc->attrs[varattno]->attname), label);
			}

			/* The tuple type is now an anonymous record type */
			tupdesc->tdtypeid = RECORDOID;
			tupdesc->tdtypmod = -1;
		}
	}
	else if (functypclass == TYPEFUNC_SCALAR)
	{
		/* Base data type, i.e. scalar */
		char	   *attname;

		/* the alias list is required for base types */
		if (colaliases == NIL)
			ereport(ERROR,
					(errcode(ERRCODE_DATATYPE_MISMATCH),
					 errmsg("no column alias was provided")));

		/* the alias list length must be 1 */
		if (list_length(colaliases) != 1)
			ereport(ERROR,
					(errcode(ERRCODE_DATATYPE_MISMATCH),
			  errmsg("number of aliases does not match number of columns")));

		/* OK, get the column alias */
		attname = strVal(linitial(colaliases));

		tupdesc = CreateTemplateTupleDesc(1, false);
		TupleDescInitEntry(tupdesc,
						   (AttrNumber) 1,
						   attname,
						   typeoid,
						   -1,
						   0);
	}
	else if (functypclass == TYPEFUNC_RECORD)
	{
		/* XXX can't support this because typmod wasn't passed in ... */
		ereport(ERROR,
				(errcode(ERRCODE_DATATYPE_MISMATCH),
				 errmsg("could not determine row description for function returning record")));
	}
	else
	{
		/* crummy error message, but parser should have caught this */
		elog(ERROR, "function in FROM has unsupported return type");
	}

	return tupdesc;
}
Example #24
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;
	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));
	}
Example #25
0
/**
 * @brief Parse function expression
 */
ParsedFunction
ParseFunction(const char *value, bool argistype)
{
    int					i;
    ParsedFunction		ret;
    char			   *buf;
    const char		   *nextp;
    bool				done = false;
    List			   *names;
    ListCell		   *l;
    int					nargs;
    FuncCandidateList	candidates;
    FuncCandidateList	find = NULL;
    int					ncandidates = 0;
    HeapTuple			ftup;
    Form_pg_proc		pp;
    AclResult			aclresult;

    buf = palloc(strlen(value) + 1);

    /* parse function name */
    nextp = value;
    do
    {
        if (*nextp == '\"')
        {
            /* Quoted name */
            for (;;)
            {
                nextp = strchr(nextp + 1, '\"');

                /* mismatched quotes */
                if (nextp == NULL)
                    ereport(ERROR,
                            (errcode(ERRCODE_SYNTAX_ERROR),
                             errmsg("function call syntax error: %s", value)));

                if (nextp[1] != '\"')
                    break;		/* found end of quoted name */
            }

            /* nextp now points at the terminating quote */
            nextp = nextp + 1;
        }
        else if (IsIdentStart((unsigned char) *nextp))
        {
            /* Unquoted name */
            nextp++;
            while (IsIdentContent((unsigned char) *nextp))
                nextp++;
        }
        else
        {
            /* invalid syntax */
            ereport(ERROR,
                    (errcode(ERRCODE_SYNTAX_ERROR),
                     errmsg("function call syntax error: %s", value)));
        }

        while (isspace((unsigned char) *nextp))
            nextp++;			/* skip trailing whitespace */

        if (*nextp == '.')
        {
            nextp++;
            while (isspace((unsigned char) *nextp))
                nextp++;		/* skip leading whitespace for next */
            /* we expect another name, so done remains false */
        }
        else if (*nextp == '\0' || *nextp == '(')
            done = true;
        else
        {
            /* invalid syntax */
            ereport(ERROR,
                    (errcode(ERRCODE_SYNTAX_ERROR),
                     errmsg("function call syntax error: %s", value)));
        }

        /* Loop back if we didn't reach end of function name */
    } while (!done);

    strncpy(buf, value, nextp - value);
    buf[nextp - value] = '\0';

    names = stringToQualifiedNameList(buf);
    pfree(buf);

    if (*nextp == '\0')
    {
        if (!argistype)
            ereport(ERROR,
                    (errcode(ERRCODE_SYNTAX_ERROR),
                     errmsg("function call syntax error: %s", value)));

        nargs = -1;

        /* Get list of possible candidates from namespace search */
        candidates = FuncnameGetCandidates(names, nargs, NIL, false, false);
    }
    else
    {
        /* parse function arguments */
        nargs = 0;
        while (GetNextArgument(nextp, &ret.args[nargs], &ret.argtypes[nargs], &nextp, value, argistype))
        {
            nargs++;
            if (nargs > FUNC_MAX_ARGS)
                ereport(ERROR,
                        (errcode(ERRCODE_TOO_MANY_ARGUMENTS),
                         errmsg("functions cannot have more than %d arguments", FUNC_MAX_ARGS)));
        }

        /* Get list of possible candidates from namespace search */
        candidates = FuncnameGetCandidates(names, nargs, NIL, true, true);
    }


    /* so now try to match up candidates */
    if (!argistype)
    {
        FuncCandidateList current_candidates;

        ncandidates = func_match_argtypes(nargs,
                                          ret.argtypes,
                                          candidates,
                                          &current_candidates);

        /* one match only? then run with it... */
        if (ncandidates == 1)
            find = current_candidates;

        /* multiple candidates? then better decide or throw an error... */
        else if (ncandidates > 1)
        {
            find = func_select_candidate(nargs, ret.argtypes,
                                         current_candidates);
        }
    }
    else if (nargs > 0)
    {
        /* Quickly check if there is an exact match to the input datatypes */
        for (find = candidates; find; find = find->next)
        {
            if (memcmp(find->args, ret.argtypes, nargs * sizeof(Oid)) == 0)
            {
                ncandidates = 1;
                break;
            }
        }
    }
    else
    {
        FuncCandidateList c;
        for (c = candidates; c; c = c->next)
            ncandidates++;
        find = candidates;
    }

    if (ncandidates == 0)
        ereport(ERROR,
                (errcode(ERRCODE_UNDEFINED_FUNCTION),
                 errmsg("function %s does not exist",
                        func_signature_string(names, nargs, NIL, ret.argtypes)),
                 errhint("No function matches the given name and argument types.")));

    /*
     * If we were able to choose a best candidate, we're done.
     * Otherwise, ambiguous function call.
     */
    if (ncandidates > 1 || !OidIsValid(find->oid))
        ereport(ERROR,
                (errcode(ERRCODE_AMBIGUOUS_FUNCTION),
                 errmsg("function %s is not unique",
                        func_signature_string(names, nargs, NIL,
                                              ret.argtypes)),
                 errhint("Could not choose a best candidate function.")));

    foreach (l, names)
    {
        Value  *v = lfirst(l);

        pfree(strVal(v));
        pfree(v);
    }
Example #26
0
// Levelpushing Trie Update
unsigned int BFLevelPushingTrieUpdate(string sFileName,CFib *tFib)
{
	unsigned int		iEntryCount = 0;						//the number of items from file
	char						sPrefix[20];								//prefix from rib file
	unsigned long	lPrefix;										//the value of Prefix
	unsigned int		iPrefixLen;								//the length of PREFIX
	int						iNextHop;								//to store NEXTHOP in RIB file

	char			operate_type_read;
	int 			operate_type;
	int			readlines = 0;
	long			updatetimeused = 0;

	long			yearmonthday=0;							//an integer to record year, month, day
	long			hourminsec=0;								//an integer to record hour, minute, second
	long			yearmonthday_old=0;					//an integer to record year, month, day
	long			hourminsec_old=0;						//an integer to record hour, minute, second
	
	long			outputCount=0;
	long			insertNum_old=0;
	long			DelNum_old=0;
	long			readlines_old=0;

	LARGE_INTEGER frequence,privious,privious1;
	
	if(!QueryPerformanceFrequency(&frequence)) return 0;

	FILE * fp_u;
	fp_u=fopen(UPDATE_TIME, "w");
	fprintf(fp_u,"Time	#update	#update_in_minute	#insertion_in_minute	#deletion_in_minute		\n");

	for (int jjj = 1; jjj <= UpdateFileCount; jjj++)
	{
		char strName[20];
		memset(strName, 0, sizeof(strName));
		sprintf(strName, "updates%d.txt", jjj);

		ifstream fin(strName);
		if (!fin)
		{
			//printf("!!!error!!!!  no file named:%s\n",strName);
			continue;
		}

		printf("\nParsing %s\n", strName);

		while (!fin.eof()) 
		{
		
			lPrefix = 0;
			iPrefixLen = 0;
			iNextHop = -9;

			memset(sPrefix,0,sizeof(sPrefix));
			
			//read data from rib file, iNextHop attention !!!
			fin >> yearmonthday >> hourminsec >> operate_type_read >> sPrefix;	//>> iNextHop;

			if('W' == operate_type_read) {
				operate_type = _DELETE;
			}
			else if ('A' == operate_type_read)
			{
				fin >> iNextHop;
				operate_type = _NOT_DELETE;
			}
			else
			{
				printf("Format of update file Error, quit....\n");
				getchar();
				return 0;
			}

			int iStart = 0;								//the end point of IP
			int iEnd = 0;								//the end point of IP
			int iFieldIndex = 3;		
			int iLen = strlen(sPrefix);			//the length of Prefix

		
			if(iLen > 0)
			{
				if (yearmonthday - yearmonthday_old > 0 || hourminsec - hourminsec_old >= 100)
				{	
					yearmonthday_old = yearmonthday;
					hourminsec_old = hourminsec;

					int hour_format = hourminsec/100;
					char hour_string[20];
					memset(hour_string, 0, sizeof(hour_string));
					if (0 == hour_format)					sprintf(hour_string, "0000");
					if (hour_format < 10)					sprintf(hour_string, "000%d", hour_format);
					else if (hour_format < 100)		sprintf(hour_string, "00%d", hour_format);
					else if (hour_format < 1000)		sprintf(hour_string, "0%d", hour_format);
					else												sprintf(hour_string, "%d", hour_format);

					if (readlines - readlines_old < 10000)
					{
						//printf("%d%s\t%u\t%u\t%u\t%d\n",yearmonthday,hour_string,readlines,readlines-readlines_old,tFib->CBFInsertNum-insertNum_old,tFib->CBFDelNum-DelNum_old);
						//fprintf(fp_u,"%d%s\t%u\t%u\t%u\t%d\n",yearmonthday,hour_string,readlines,readlines-readlines_old,tFib->CBFInsertNum-insertNum_old,tFib->CBFDelNum-DelNum_old);
					}

					insertNum_old = tFib->CBFInsertNum;
					DelNum_old = tFib->CBFDelNum;
					readlines_old = readlines;
					//printf("%d%s\t%d\t%u\t%d\t%d\t%d\n",yearmonthday,hour_string,readlines,tFib->trueUpdateNum,tFib->CBFInsertNum,tFib->CBFDelNum,tFib->invalid);

					//fprintf(fp_u,"%d%s\t%d\t%u\t%d\t%d\t%d\n",yearmonthday,hour_string,readlines,tFib->trueUpdateNum,tFib->CBFInsertNum,tFib->CBFDelNum,tFib->invalid);

					//fprintf(fp_u,"%d%d\t%d\t%d\t%d\t%d\n",yearmonthday,hourminsec,readlines,tFib->solidNodeCount,tFib->oldNodeCount,updatetimeused);
				}

				readlines++;
				for ( int i=0; i<iLen; i++ )
				{
					//extract the first 3 sub-part
					if ( sPrefix[i] == '.' )
					{
						iEnd = i;
						string strVal(sPrefix + iStart, iEnd - iStart);
						lPrefix += atol(strVal.c_str()) << (8 * iFieldIndex); //向左移位到高位
						iFieldIndex--;
						iStart = i + 1;
						i++;
					}

					if ( sPrefix[i] == '/' ) {
						//extract the 4th sub-part
						iEnd = i;
						string strVal(sPrefix + iStart, iEnd - iStart);
						lPrefix += atol(strVal.c_str());
						iStart = i + 1;

						//extract the length of prefix
						i++;
						strVal = string(sPrefix + iStart, iLen - 1);
						iPrefixLen = atoi(strVal.c_str());
					}
				}

				char insert_C[50];
				memset(insert_C,0,sizeof(insert_C));
				//insert the current node into Trie tree
				for (unsigned int yi = 0; yi < iPrefixLen; yi++)
				{
					//turn right
					if(((lPrefix << yi) & HIGHTBIT) == HIGHTBIT) insert_C[yi]='1';
					else insert_C[yi]='0';
				}
				//printf("%s\/%d\t%d\n",insert_C,iPrefixLen,iNextHop);

				if (iPrefixLen < 8) {
					printf("%d-%d; ", iPrefixLen, iNextHop);
				}
				else
				{
					QueryPerformanceCounter(&privious); 
					
					tFib->Update(iNextHop, insert_C, operate_type);

					QueryPerformanceCounter(&privious1);
					updatetimeused+=1000000*(privious1.QuadPart-privious.QuadPart)/frequence.QuadPart;
				}
			}
		}
Example #27
0
/*
 * CommentObject --
 *
 * This routine is used to add the associated comment into
 * pg_description for the object specified by the given SQL command.
 */
Oid
CommentObject(CommentStmt *stmt)
{
	ObjectAddress address;
	Relation	relation;

	/*
	 * When loading a dump, we may see a COMMENT ON DATABASE for the old name
	 * of the database.  Erroring out would prevent pg_restore from completing
	 * (which is really pg_restore's fault, but for now we will work around
	 * the problem here).  Consensus is that the best fix is to treat wrong
	 * database name as a WARNING not an ERROR; hence, the following special
	 * case.  (If the length of stmt->objname is not 1, get_object_address
	 * will throw an error below; that's OK.)
	 */
	if (stmt->objtype == OBJECT_DATABASE && list_length(stmt->objname) == 1)
	{
		char	   *database = strVal(linitial(stmt->objname));

		if (!OidIsValid(get_database_oid(database, true)))
		{
			ereport(WARNING,
					(errcode(ERRCODE_UNDEFINED_DATABASE),
					 errmsg("database \"%s\" does not exist", database)));
			return InvalidOid;
		}
	}

	/*
	 * Translate the parser representation that identifies this object into an
	 * ObjectAddress.  get_object_address() will throw an error if the object
	 * does not exist, and will also acquire a lock on the target to guard
	 * against concurrent DROP operations.
	 */
	address = get_object_address(stmt->objtype, stmt->objname, stmt->objargs,
								 &relation, ShareUpdateExclusiveLock, false);

	/* Require ownership of the target object. */
	check_object_ownership(GetUserId(), stmt->objtype, address,
						   stmt->objname, stmt->objargs, relation);

	/* Perform other integrity checks as needed. */
	switch (stmt->objtype)
	{
		case OBJECT_COLUMN:

			/*
			 * Allow comments only on columns of tables, views, composite
			 * types, and foreign tables (which are the only relkinds for
			 * which pg_dump will dump per-column comments).  In particular we
			 * wish to disallow comments on index columns, because the naming
			 * of an index's columns may change across PG versions, so dumping
			 * per-column comments could create reload failures.
			 */
			if (relation->rd_rel->relkind != RELKIND_RELATION &&
				relation->rd_rel->relkind != RELKIND_VIEW &&
				relation->rd_rel->relkind != RELKIND_COMPOSITE_TYPE &&
				relation->rd_rel->relkind != RELKIND_FOREIGN_TABLE)
				ereport(ERROR,
						(errcode(ERRCODE_WRONG_OBJECT_TYPE),
						 errmsg("\"%s\" is not a table, view, composite type, or foreign table",
								RelationGetRelationName(relation))));
			break;
		default:
			break;
	}

	/*
	 * Databases, tablespaces, and roles are cluster-wide objects, so any
	 * comments on those objects are recorded in the shared pg_shdescription
	 * catalog.  Comments on all other objects are recorded in pg_description.
	 */
	if (stmt->objtype == OBJECT_DATABASE || stmt->objtype == OBJECT_TABLESPACE
		|| stmt->objtype == OBJECT_ROLE)
		CreateSharedComments(address.objectId, address.classId, stmt->comment);
	else
		CreateComments(address.objectId, address.classId, address.objectSubId,
					   stmt->comment);

	/*
	 * If get_object_address() opened the relation for us, we close it to keep
	 * the reference count correct - but we retain any locks acquired by
	 * get_object_address() until commit time, to guard against concurrent
	 * activity.
	 */
	if (relation != NULL)
		relation_close(relation, NoLock);

	return address.objectId;
}
Example #28
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);
}
Example #29
0
/*
 * Preprocess the query string and build up hash_cookie, which will be
 * passed to caql_switch later.
 */
struct caql_hash_cookie *
cq_lookup(const char *str, unsigned int len, cq_list *pcql)
{
	Node				   *query;
	struct caql_hash_cookie *hash_cookie;

	hash_cookie = caql_get_parser_cache(str, len);
	if (hash_cookie != NULL)
		return hash_cookie;

	query = caql_raw_parser(str, (const char *) pcql->filename, pcql->lineno);
	if (query == NULL)
		return NULL;

	hash_cookie = palloc0(sizeof(struct caql_hash_cookie));
	switch(nodeTag(query))
	{
	case T_CaQLSelect:
		{
			CaQLSelect	   *node = (CaQLSelect *) query;
			char		   *attname;

			if (node->forupdate)
				hash_cookie->bUpdate = true;
			if (node->count)
				hash_cookie->bCount = true;

			hash_cookie->relation = catcore_lookup_rel(node->from);
			if (hash_cookie->relation == NULL)
				elog(ERROR, "could not find relation \"%s\" in %s at %s:%d",
							node->from, str, pcql->filename, pcql->lineno);

			attname = strVal(linitial(node->targetlist));

			/*
			 * Look up attribute number if target list has a column.
			 * '*' includes count('*').  The first character test is
			 * not wrong due to the syntax limitation, and this is quick.
			 */
			if (attname[0] != '*')
			{
				hash_cookie->attnum =
					catcore_lookup_attnum(hash_cookie->relation, attname,
										  &hash_cookie->atttype);
				if (hash_cookie->attnum == InvalidAttrNumber)
					elog(ERROR, "could not find attribute \"%s\" in %s at %s:%d",
								attname, str, pcql->filename, pcql->lineno);
			}

			hash_cookie->bAllEqual =
				caql_process_predicates(hash_cookie, node->where);
		}
		break;
	case T_CaQLInsert:
		{
			CaQLInsert	   *node = (CaQLInsert *) query;

			hash_cookie->bInsert = true;

			hash_cookie->relation = catcore_lookup_rel(node->into);
			if (hash_cookie->relation == NULL)
				elog(ERROR, "could not find relation \"%s\" in %s at %s:%d",
							node->into, str, pcql->filename, pcql->lineno);

		}
		break;
	case T_CaQLDelete:
		{
			CaQLDelete	   *node = (CaQLDelete *) query;

			hash_cookie->bDelete = true;

			hash_cookie->relation = catcore_lookup_rel(node->from);
			if (hash_cookie->relation == NULL)
				elog(ERROR, "could not find relation \"%s\" in %s at %s:%d",
							node->from, str, pcql->filename, pcql->lineno);

			hash_cookie->bAllEqual =
				caql_process_predicates(hash_cookie, node->where);
		}
		break;
	default:
		return NULL;
	}

	hash_cookie->name = str;
	hash_cookie->query = query;
	hash_cookie->file = (char *) pcql->filename;
	hash_cookie->lineno = pcql->lineno;
	/* Find an available index based on predicates or ORDER BY */
	hash_cookie->index = caql_find_index(hash_cookie, query);
	if (hash_cookie->index != NULL)
		hash_cookie->syscacheid = GetSysCacheId(hash_cookie->index->indexoid);
	else
		hash_cookie->syscacheid = -1;

	caql_put_parser_cache(str, len, hash_cookie);

	return hash_cookie;
}
Example #30
0
static void yaz_xml2query_term(const xmlNode *ptr, Z_Term **term, ODR odr,
                               int *error_code, const char **addinfo)
{
    xmlChar *type = 0;
    struct _xmlAttr *attr;
    char *cdata = strVal(ptr->children, odr);

    for (attr = ptr->properties; attr; attr = attr->next)
    {
        if (!xmlStrcmp(attr->name, BAD_CAST "type") &&
            attr->children && attr->children->type == XML_TEXT_NODE)
            type = attr->children->content;
        else
        {
            *error_code = 1;
            *addinfo = "bad attribute for attr content";
            return;
        }
    }
    *term = (Z_Term *) odr_malloc(odr, sizeof(Z_Term));

    if (!type || !xmlStrcmp(type, BAD_CAST "general"))
    {
        (*term)->which = Z_Term_general;
        (*term)->u.general =
            odr_create_Odr_oct(odr, cdata, strlen(cdata));
    }
    else if (!xmlStrcmp(type, BAD_CAST "numeric"))
    {
        (*term)->which = Z_Term_numeric;
        (*term)->u.numeric = intVal(odr, cdata);
    }
    else if (!xmlStrcmp(type, BAD_CAST "string"))
    {
        (*term)->which = Z_Term_characterString;
        (*term)->u.characterString = cdata;
    }
    else if (!xmlStrcmp(type, BAD_CAST "oid"))
    {
        *error_code = 1;
        *addinfo = "unhandled term type: oid";
    }
    else if (!xmlStrcmp(type, BAD_CAST "dateTime"))
    {
        *error_code = 1;
        *addinfo = "unhandled term type: dateTime";
    }
    else if (!xmlStrcmp(type, BAD_CAST "integerAndUnit"))
    {
        *error_code = 1;
        *addinfo = "unhandled term type: integerAndUnit";
    }
    else if (!xmlStrcmp(type, BAD_CAST "null"))
    {
        (*term)->which = Z_Term_null;
        (*term)->u.null = odr_nullval();
    }
    else
    {
        *error_code = 1;
        *addinfo = "unhandled term type";
    }
}