Beispiel #1
0
Datum
caql_copy_to_in_memory_pg_class(PG_FUNCTION_ARGS)
{

	text *inText = PG_GETARG_TEXT_P(0);;
	char *inStr = text_to_cstring(inText);
	char kind = PG_GETARG_CHAR(1);

	StringInfoData buf;
	initStringInfo(&buf);

	/* create tuples for pg_class table */
	HeapTuple reltup = NULL;
	HeapTuple copytup = NULL;
	Form_pg_class relform;
	cqContext  *pcqCtx;
	cqContext  *pcqCtxInsert;

	pcqCtx = caql_beginscan(
			NULL,
			cql("SELECT * FROM pg_class "
				" WHERE relname = :1",
				CStringGetDatum((char *) inStr)));

	reltup = caql_getnext(pcqCtx);

	if (NULL == reltup)
	{
		appendStringInfo(&buf, "no tuples with relname=%s found!", inStr);
	}
	else
	{
	    copytup = heaptuple_copy_to(reltup, NULL, NULL);

		relform = (Form_pg_class) GETSTRUCT(copytup);
		relform->relkind = kind;
		appendStringInfo(&buf, "table pg_class, insert 1 line (relname %s, relkind %c)", NameStr(relform->relname), kind);

		/* insert */
		pcqCtxInsert = caql_beginscan(
				NULL,
				cql("INSERT INTO pg_class", NULL));
		caql_insert_inmem(pcqCtxInsert, copytup);
		caql_endscan(pcqCtxInsert);

		heap_freetuple(copytup);
	}

	caql_endscan(pcqCtx);

	PG_RETURN_TEXT_P(cstring_to_text(buf.data));
}
Beispiel #2
0
/*
 * TypeRename
 *		This renames a type
 *
 * Note: any associated array type is *not* renamed; caller must make
 * another call to handle that case.  Currently this is only used for
 * renaming types associated with tables, for which there are no arrays.
 */
void
TypeRename(Oid typeOid, const char *newTypeName)
{
	Relation		pg_type_desc;
	HeapTuple		tuple;
	Form_pg_type	form;
	cqContext	   *pcqCtx;
	cqContext		cqc, cqc2;

	pg_type_desc = heap_open(TypeRelationId, RowExclusiveLock);

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

	tuple = caql_getfirst(
			pcqCtx,
			cql("SELECT * FROM pg_type "
				" WHERE oid = :1 "
				" FOR UPDATE ",
				ObjectIdGetDatum(typeOid)));

	if (!HeapTupleIsValid(tuple))
		ereport(ERROR,
				(errcode(ERRCODE_UNDEFINED_OBJECT),
				 errmsg("type with OID \"%d\" does not exist", typeOid)));

	form = (Form_pg_type) GETSTRUCT(tuple);
	if (namestrcmp(&(form->typname), newTypeName))
	{
		if (caql_getcount(
					caql_addrel(cqclr(&cqc2), pg_type_desc),
					cql("SELECT COUNT(*) FROM pg_type "
						" WHERE typname = :1 "
						" AND typnamespace = :2 ",
						CStringGetDatum((char *) newTypeName),
						ObjectIdGetDatum(form->typnamespace))))
		{
			ereport(ERROR,
					(errcode(ERRCODE_DUPLICATE_OBJECT),
					 errmsg("type \"%s\" already exists", newTypeName)));
		}

		namestrcpy(&(form->typname), newTypeName);

		caql_update_current(pcqCtx, tuple);
		/* update the system catalog indexes (implicit) */
	}

	heap_freetuple(tuple);
	heap_close(pg_type_desc, RowExclusiveLock);
}
Beispiel #3
0
/*
 * IsErrorTable
 *
 * Returns true if relid is used as an error table, which has dependent object
 * that is an external table.  Though it's not great we didn't have a clear
 * definition of Error Table, it satisfies the current requirements.
 */
bool
IsErrorTable(Relation rel)
{
	cqContext	   *pcqCtx, *pcqCtxExt, ctxExt;
	HeapTuple		tup;
	Relation		extrel;
	bool			result = false;

	/* fast path to quick check */
	if (!RelationIsHeap(rel))
		return false;

	/*
	 * Otherwise, go deeper and play with pg_depend...
	 */
	pcqCtx = caql_beginscan(NULL,
							cql("SELECT * FROM pg_depend "
								" WHERE refclassid = :1 "
								" AND refobjid = :2 "
								" AND refobjsubid = :3 ",
								ObjectIdGetDatum(RelationRelationId),
								ObjectIdGetDatum(RelationGetRelid(rel)),
								Int32GetDatum(0)));

	extrel = relation_open(ExtTableRelationId, AccessShareLock);
	pcqCtxExt = caql_addrel(cqclr(&ctxExt), extrel);

	while (HeapTupleIsValid(tup = caql_getnext(pcqCtx)))
	{
		Form_pg_depend dep = (Form_pg_depend) GETSTRUCT(tup);
		Oid				fmterrtbl;

		fmterrtbl = caql_getoid(pcqCtxExt,
								cql("SELECT fmterrtbl FROM pg_exttable "
									" WHERE reloid = :1",
									ObjectIdGetDatum(dep->objid)));
		if (RelationGetRelid(rel) == fmterrtbl)
		{
			result = true;
			break;
		}
	}

	relation_close(extrel, AccessShareLock);

	caql_endscan(pcqCtx);

	return result;
}
Beispiel #4
0
/*
 * Obtain the dbid of a of a segment at a given segment index (i.e., content id)
 * currently fulfilling the role specified. This means that the segment is
 * really performing the role of primary or mirror, irrespective of their
 * preferred role.
 */
int16
contentid_get_dbid(int16 contentid, char role, bool getPreferredRoleNotCurrentRole)
{
	int16 dbid = 0;
	bool bOnly;
	HeapTuple tup;

	/*
	 * Can only run on a master node, this restriction is due to the reliance
	 * on the gp_segment_configuration table.  This may be able to be relaxed
	 * by switching to a different method of checking.
	 */
	if (GpIdentity.segindex != MASTER_CONTENT_ID)
		elog(ERROR, "contentid_get_dbid() executed on execution segment");

	/* XXX XXX: CHECK THIS  XXX jic 2011/12/09 */
	if (getPreferredRoleNotCurrentRole)
	{
		tup = caql_getfirst_only(
				NULL,
				&bOnly,
				cql("SELECT * FROM gp_segment_configuration "
					" WHERE content = :1 "
					" AND preferred_role = :2 ",
					Int16GetDatum(contentid),
					CharGetDatum(role)));
	}
	else
	{
		tup = caql_getfirst_only(
				NULL,
				&bOnly,
				cql("SELECT * FROM gp_segment_configuration "
					" WHERE content = :1 "
					" AND role = :2 ",
					Int16GetDatum(contentid),
					CharGetDatum(role)));
	}

	if (HeapTupleIsValid(tup))
	{
		dbid = ((Form_gp_segment_configuration) GETSTRUCT(tup))->dbid;
		/* We expect a single result, assert this */
		Assert(bOnly); /* should be only 1 */
	}
	/* no need to hold the lock, it's a catalog */

	return dbid;
}
Beispiel #5
0
Datum
caql_insert_to_in_memory_pg_attribute(PG_FUNCTION_ARGS)
{
	Oid attrelid = PG_GETARG_OID(0);
	char *attname = text_to_cstring(PG_GETARG_TEXT_P(1));
	AttrNumber attno = PG_GETARG_INT16(2);

	cqContext  *pcqCtx = caql_beginscan(
			NULL,
			cql("INSERT INTO pg_attribute", NULL));
	
	FormData_pg_attribute attributeD;
	HeapTuple attributeTuple = heap_addheader(Natts_pg_attribute,
									false,
									ATTRIBUTE_TUPLE_SIZE,
									(void *) &attributeD);
	
	Form_pg_attribute attribute = (Form_pg_attribute) GETSTRUCT(attributeTuple);
	
	attribute->attrelid = attrelid;
	namestrcpy(&(attribute->attname), attname);
	attribute->attnum = attno;

	caql_insert_inmem(pcqCtx, attributeTuple);
	caql_endscan(pcqCtx);
	
	StringInfoData buf;
	initStringInfo(&buf);

	appendStringInfo(&buf, "inserted tuple to pg_attribute (attrelid %d, attname %s, attno %d)", attribute->attrelid, NameStr(attribute->attname), attribute->attnum);

	PG_RETURN_TEXT_P(cstring_to_text(buf.data));
}
Beispiel #6
0
/*
 * Record a type's default encoding clause in the catalog.
 */
void
add_type_encoding(Oid typid, Datum typoptions)
{
	Datum		 values[Natts_pg_type_encoding];
	bool		 nulls[Natts_pg_type_encoding];
	HeapTuple	 tuple;
	cqContext	*pcqCtx;

	pcqCtx = caql_beginscan(
			NULL,
			cql("INSERT INTO pg_type_encoding ",
				NULL));

	MemSet(nulls, false, sizeof(nulls));
	
	values[Anum_pg_type_encoding_typid - 1] = ObjectIdGetDatum(typid);
	values[Anum_pg_type_encoding_typoptions - 1] = typoptions;

	tuple = caql_form_tuple(pcqCtx, values, nulls);

	/* Insert tuple into the relation */
	caql_insert(pcqCtx, tuple); /* implicit update of index as well */

	caql_endscan(pcqCtx);
}
/*
 * Add a single attribute encoding entry.
 */
static void
add_attribute_encoding_entry(Oid relid, AttrNumber attnum, Datum attoptions)
{
	Datum values[Natts_pg_attribute_encoding];
	bool nulls[Natts_pg_attribute_encoding];
	HeapTuple tuple;
	cqContext	   *pcqCtx;
	
	Insist(!gp_upgrade_mode);
	Insist(attnum != InvalidAttrNumber);
	
	pcqCtx = caql_beginscan(
			NULL,
			cql("INSERT INTO pg_attribute_encoding",
				NULL));

	MemSet(nulls, 0, sizeof(nulls));
	values[Anum_pg_attribute_encoding_attrelid - 1] = ObjectIdGetDatum(relid);
	values[Anum_pg_attribute_encoding_attnum - 1] = Int16GetDatum(attnum);
	values[Anum_pg_attribute_encoding_attoptions - 1] = attoptions;

	tuple = caql_form_tuple(pcqCtx, values, nulls);

	/* insert a new tuple */
	caql_insert(pcqCtx, tuple); /* implicit update of index as well */

	heap_freetuple(tuple);

	caql_endscan(pcqCtx);
}
Beispiel #8
0
/*
 * Removes the policy of a table from the gp_distribution_policy table
 *
 * Callers must check that there actually *is* a policy for the relation.
 */
void
GpPolicyRemove(Oid tbloid)
{
	Relation	gp_policy_rel;
	cqContext	cqc;

    /*
     * Open and lock the gp_distribution_policy catalog.
     */
	gp_policy_rel = heap_open(GpPolicyRelationId, RowExclusiveLock);

	/* Delete the policy entry from the catalog. */
	if (0 == caql_getcount(
				caql_addrel(cqclr(&cqc), gp_policy_rel),
				cql("DELETE FROM gp_distribution_policy "
					" WHERE localoid = :1 ",
					ObjectIdGetDatum(tbloid))))
	{
		ereport(ERROR,
				(errcode(ERRCODE_UNDEFINED_OBJECT),
				 errmsg("distribution policy for relation \"%d\" does not exist",
						tbloid)));
	}

	/*
     * Close the gp_distribution_policy relcache entry without unlocking.
     * We have updated the catalog: consequently the lock must be held until
     * end of transaction.
     */
    heap_close(gp_policy_rel, NoLock);
}                               /* GpPolicyRemove */
Beispiel #9
0
/*
 * FindConversion
 *
 * Find conversion by namespace and conversion name.
 * Returns conversion OID.
 */
Oid
FindConversion(const char *conname, Oid connamespace)
{
	HeapTuple	tuple;
	Oid			procoid;
	Oid			conoid;
	AclResult	aclresult;
	cqContext  *pcqCtx;

	/* search pg_conversion by connamespace and conversion name */
	pcqCtx = caql_beginscan(
			NULL,
			cql("SELECT * FROM pg_conversion "
				" WHERE conname = :1 "
				" AND connamespace = :2 ",
				CStringGetDatum((char *) conname),
				ObjectIdGetDatum(connamespace)));

	tuple = caql_getnext(pcqCtx);

	if (!HeapTupleIsValid(tuple))
		return InvalidOid;

	procoid = ((Form_pg_conversion) GETSTRUCT(tuple))->conproc;
	conoid = HeapTupleGetOid(tuple);

	caql_endscan(pcqCtx);

	/* Check we have execute rights for the function */
	aclresult = pg_proc_aclcheck(procoid, GetUserId(), ACL_EXECUTE);
	if (aclresult != ACLCHECK_OK)
		return InvalidOid;

	return conoid;
}
Beispiel #10
0
/*
 * ConversionDrop
 *
 * Drop a conversion after doing permission checks.
 */
void
ConversionDrop(Oid conversionOid, DropBehavior behavior)
{
	HeapTuple	tuple;
	ObjectAddress object;
	cqContext  *pcqCtx;

	pcqCtx = caql_beginscan(
			NULL,
			cql("SELECT * FROM pg_conversion "
				" WHERE oid = :1 ",
				ObjectIdGetDatum(conversionOid)));

	tuple = caql_getnext(pcqCtx);

	if (!HeapTupleIsValid(tuple))
		elog(ERROR, "cache lookup failed for conversion %u", conversionOid);

	if (!superuser() &&
		((Form_pg_conversion) GETSTRUCT(tuple))->conowner != GetUserId())
		aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CONVERSION,
				  NameStr(((Form_pg_conversion) GETSTRUCT(tuple))->conname));

	caql_endscan(pcqCtx);

	/*
	 * Do the deletion
	 */
	object.classId = ConversionRelationId;
	object.objectId = conversionOid;
	object.objectSubId = 0;

	performDeletion(&object, behavior);
}
Beispiel #11
0
void QueryExpression::setQueryContext(QueryContext& inCtx)
{
  if(_ss == NULL){
    MessageLoaderParms parms("Query.QueryExpression.SS_IS_NULL",
                             "Trying to process a query with a NULL SelectStatement.");
    throw QueryException(parms);
  }

  // SelectStatement only allows this to be called once.
  _ss->setQueryContext(inCtx);

#ifndef PEGASUS_DISABLE_CQL
  String cql("CIM:CQL");

  if (_queryLang == cql)
  {
    // Now that we have a QueryContext, we can finish compiling
    // the CQL statement.
    CQLSelectStatement* tempSS = dynamic_cast<CQLSelectStatement*>(_ss);
    if (tempSS != NULL)
    {
      CQLParser::parse(getQuery(), *tempSS);
      tempSS->applyContext();
    }
  }
#endif
}
/*
 * Does a compression algorithm exist by the name of `compresstype'?
 */
bool
compresstype_is_valid(char *comptype)
{
	NameData	compname;
	bool		found = false;

	compname = comptype_to_name(comptype);

	found = (0 !=
			 caql_getcount(
					 NULL,
					 cql("SELECT COUNT(*) FROM pg_compression "
						 " WHERE compname = :1 ",
						 NameGetDatum(&compname))));

	/*
	 * FIXME: This is a hack. Should implement related handlers and register 
	 * in system tables instead. snappy handlers have already been implemented
	 * but not registerd in system tables (see comment in GetCompressionImplement()
	 * for details).
	 */
	if(!found)
	{
		if(strcmp(comptype, "snappy") == 0 || strcmp(comptype, "gzip") == 0)
			found = true;
	}

	return found;
}
void update_segment_status_by_id(uint32_t id, char status)
{
	/* we use AccessExclusiveLock to prevent races */
	Relation rel = heap_open(GpSegmentConfigRelationId, AccessExclusiveLock);
	HeapTuple tuple;
	cqContext	cqc;
	cqContext  *pcqCtx;

	Assert(status == 'u' || status == 'd');

	pcqCtx = caql_beginscan(caql_addrel(cqclr(&cqc), rel),
						cql("SELECT * FROM gp_segment_configuration "
							" WHERE registration_order = :1 "
							" FOR UPDATE ",
							Int32GetDatum(id)));

	tuple = caql_getnext(pcqCtx);

	if (tuple != NULL) {
		if (((Form_gp_segment_configuration)GETSTRUCT(tuple))->status != status) {
			((Form_gp_segment_configuration)GETSTRUCT(tuple))->status = status;
			caql_update_current(pcqCtx, tuple);
		}
	} else {
		elog(LOG, "Can not find segment id: %d when update its status", id);
	}

	caql_endscan(pcqCtx);

	heap_close(rel, NoLock);
}
Beispiel #14
0
/*
 * Same as LookupExtProtocolFunction but returns the actual
 * protocol Oid.
 */
Oid
LookupExtProtocolOid(const char *prot_name, bool missing_ok)
{
	int			fetchCount;
	Oid			protOid = InvalidOid;
	
	/*
	 * Check the pg_extprotocol relation to be certain the protocol
	 * is there.
	 */
	protOid = caql_getoid_plus(
			NULL,
			&fetchCount,
			NULL,
			cql("SELECT oid FROM pg_extprotocol "
				" WHERE ptcname = :1 ",
				CStringGetDatum(prot_name)));

	if (0 == fetchCount)
	{
		if(!missing_ok)
			ereport(ERROR,
					(errcode(ERRCODE_UNDEFINED_OBJECT),
					 errmsg("protocol \"%s\" does not exist",
							prot_name)));
	}
	
	return protOid;

}
Beispiel #15
0
char *
ExtProtocolGetNameByOid(Oid	protOid)
{		
	char		*ptcnamestr;
	bool		isNull;
	int			fetchCount;
	
	/*
	 * Search pg_extprotocol.  We use a heapscan here even though there is an
	 * index on oid, on the theory that pg_extprotocol will usually have just a
	 * few entries and so an indexed lookup is a waste of effort.
	 */

	ptcnamestr = caql_getcstring_plus(
			NULL,
			&fetchCount,
			&isNull,
			cql("SELECT ptcname FROM pg_extprotocol "
				" WHERE oid = :1 ",
				ObjectIdGetDatum(protOid)));

	/* We assume that there can be at most one matching tuple */
	if (!fetchCount)
	{
		elog(ERROR, "protocol %u could not be found", protOid);
	}

	if(isNull)
		ereport(ERROR,
			(errcode(ERRCODE_UNDEFINED_OBJECT),
			 errmsg("internal error: protocol '%u' has no name defined",
					 protOid)));

	return ptcnamestr;
}
Beispiel #16
0
/*
 * Removes the policy of a table from the gp_distribution_policy table

 * Does nothing if the policy doesn't exist.
 */
void
GpPolicyRemove(Oid tbloid)
{
	Relation	gp_policy_rel;
	cqContext	cqc;

    /*
     * Open and lock the gp_distribution_policy catalog.
     */
	gp_policy_rel = heap_open(GpPolicyRelationId, RowExclusiveLock);

	/* Delete the policy entry from the catalog. */
	(void) caql_getcount(
		caql_addrel(cqclr(&cqc), gp_policy_rel),
		cql("DELETE FROM gp_distribution_policy "
			" WHERE localoid = :1 ",
			ObjectIdGetDatum(tbloid)));

	/*
     * Close the gp_distribution_policy relcache entry without unlocking.
     * We have updated the catalog: consequently the lock must be held until
     * end of transaction.
     */
    heap_close(gp_policy_rel, NoLock);
}                               /* GpPolicyRemove */
Beispiel #17
0
/*
 * assign_func_result_transient_type
 *		assign typmod if the result of function is transient type.
 *
 */
void
assign_func_result_transient_type(Oid funcid)
{
	HeapTuple	tp;
	Form_pg_proc procform;
	TupleDesc	tupdesc;
	cqContext  *pcqCtx;

	pcqCtx = caql_beginscan(
			NULL,
			cql("SELECT * FROM pg_proc "
				" WHERE oid = :1 ",
				ObjectIdGetDatum(funcid)));

	tp = caql_getnext(pcqCtx);

	caql_endscan(pcqCtx);

	if (!HeapTupleIsValid(tp))
		elog(ERROR, "cache lookup failed for function %u", funcid);
	procform = (Form_pg_proc) GETSTRUCT(tp);

	tupdesc = build_function_result_tupdesc_t(tp);
	if (tupdesc == NULL)
		return;

	if (resolve_polymorphic_tupdesc(tupdesc,
									&procform->proargtypes,
									NULL))
	{
		if (tupdesc->tdtypeid == RECORDOID &&
			tupdesc->tdtypmod < 0)
			assign_record_type_typmod(tupdesc);
	}
}
Beispiel #18
0
QueryExpression QueryExpression::operator=(const QueryExpression& rhs)
{
  if (this == &rhs)
    return *this;

  if (_ss != NULL)
    delete _ss;
  _ss = NULL;

  if (rhs._ss != NULL)
  {
    String cql("CIM:CQL");
    String wql("WQL");

#ifndef PEGASUS_DISABLE_CQL
    if (rhs._queryLang == cql)
    {
      CQLSelectStatement* tempSS = dynamic_cast<CQLSelectStatement*>(rhs._ss);
      if (tempSS != NULL)
        _ss = new CQLSelectStatement(*tempSS);
    }
    else 
#endif
    if (rhs._queryLang == wql)
    {
      WQLSelectStatement* tempSS = dynamic_cast<WQLSelectStatement*>(rhs._ss);
      if (tempSS != NULL)
        _ss = new WQLSelectStatement(*tempSS);
    }
  }

  _queryLang = rhs._queryLang;

  return *this;
}
Beispiel #19
0
/* MPP-6923: 
 * GetResourceTypeByName: find the named resource in pg_resourcetype
 *
 * Input: name of resource
 * Output: resourcetypid (int2), oid of entry
 *
 * updates output and returns true if named resource found
 *
*/
static
bool GetResourceTypeByName(char *pNameIn, int *pTypeOut, Oid *pOidOut)
{
	HeapTuple	tuple;
	bool		bStat = false;

	/* XXX XXX: maybe should be share lock, ie remove FOR UPDATE ? */
	/* XXX XXX: only one */

	tuple = caql_getfirst(
			NULL,
			cql("SELECT * FROM pg_resourcetype" 
				" WHERE resname = :1 FOR UPDATE", 
				CStringGetDatum(pNameIn)));
	

	if (HeapTupleIsValid(tuple))
	{
		*pOidOut = HeapTupleGetOid(tuple);
		*pTypeOut =
				((Form_pg_resourcetype) GETSTRUCT(tuple))->restypid;
		bStat = true;
	}

	return (bStat);
} /* end GetResourceTypeByName */
Beispiel #20
0
/*
 * Determine the dbid for the master standby
 */
int16
master_standby_dbid(void)
{
	int16 dbid = 0;
	int16 contentid = -1;
	bool bOnly;
	HeapTuple tup;

	/*
	 * Can only run on a master node, this restriction is due to the reliance
	 * on the gp_segment_configuration table.
	 */
	if (GpIdentity.segindex != MASTER_CONTENT_ID)
		elog(ERROR, "master_standby_dbid() executed on execution segment");

	tup = caql_getfirst_only(
			NULL,
			&bOnly,
			cql("SELECT * FROM gp_segment_configuration "
				" WHERE content = :1 "
				" AND role = :2 ",
				Int16GetDatum(contentid),
				CharGetDatum('m')));

	if (HeapTupleIsValid(tup))
	{
		dbid = ((Form_gp_segment_configuration) GETSTRUCT(tup))->dbid;
		/* We expect a single result, assert this */
		Assert(bOnly);
	}
	/* no need to hold the lock, it's a catalog */

	return dbid;
}
Beispiel #21
0
QueryExpression::QueryExpression(const QueryExpression& expr):
  _queryLang(expr._queryLang)
{
  if (expr._ss == NULL)
  {
    _ss = NULL;
  }
  else
  {
    _ss = NULL;

    String cql("CIM:CQL");
    String wql("WQL");

#ifndef PEGASUS_DISABLE_CQL
    if (expr._queryLang == cql)
    {
      CQLSelectStatement* tempSS = dynamic_cast<CQLSelectStatement*>(expr._ss);
      if (tempSS != NULL)
        _ss = new CQLSelectStatement(*tempSS);
    }
    else 
#endif
    if (expr._queryLang == wql)
    {
      WQLSelectStatement* tempSS = dynamic_cast<WQLSelectStatement*>(expr._ss);
      if (tempSS != NULL)
        _ss = new WQLSelectStatement(*tempSS);
    }
  }
}
/*
 * Remove the master standby.
 *
 * gp_remove_master_standby()
 *
 * Returns:
 *  true upon success otherwise false
 */
Datum
gp_remove_master_standby(PG_FUNCTION_ARGS)
{
	int numDel;
	cqContext	cqc;

	mirroring_sanity_check(SUPERUSER | MASTER_ONLY | UTILITY_MODE,
						   "gp_remove_master_standby");

	if (!standby_exists())
		elog(ERROR, "no master standby defined");

	Relation rel = heap_open(GpSegmentConfigRelationId, AccessExclusiveLock);
	numDel= caql_getcount(caql_addrel(cqclr(&cqc), rel),
				cql("DELETE FROM gp_segment_configuration "
					" WHERE role = :1",
					CharGetDatum(SEGMENT_ROLE_STANDBY_CONFIG)));

	elog(LOG, "Remove standby, count : %d.", numDel);

	heap_close(rel, NoLock);

	update_gp_master_mirroring("Not Configured");

	PG_RETURN_BOOL(true);
}
/*
 * Activate a standby. To do this, we need to change
 *
 * 1. Check that we're actually the standby
 * 2. Remove standby from gp_segment_configuration.
 *
 * gp_activate_standby()
 *
 * Returns:
 *  true upon success, otherwise throws error.
 */
Datum
gp_activate_standby(PG_FUNCTION_ARGS)
{
	cqContext cqc;
	int numDel;
	mirroring_sanity_check(SUPERUSER | UTILITY_MODE | STANDBY_ONLY,
						   PG_FUNCNAME_MACRO);

	if (!AmIStandby())
		elog(ERROR, "%s must be run on the standby master",
			 PG_FUNCNAME_MACRO);

	/* remove standby from gp_segment_configuration */
	Relation rel = heap_open(GpSegmentConfigRelationId, AccessExclusiveLock);
	numDel= caql_getcount(caql_addrel(cqclr(&cqc), rel),
				cql("DELETE FROM gp_segment_configuration "
					" WHERE role = :1",
					CharGetDatum(SEGMENT_ROLE_STANDBY_CONFIG)));

	elog(LOG, "Remove standby while activating it, count : %d.", numDel);

	heap_close(rel, NoLock);

	/* done */
	PG_RETURN_BOOL(true);
}
Beispiel #24
0
/*
 * transformArrayType()
 *		Get the element type of an array type in preparation for subscripting
 */
Oid
transformArrayType(Oid arrayType)
{
	Oid			elementType;
	int			fetchCount;

	/* Get the type tuple for the array */
	elementType = caql_getoid_plus(
			NULL,
			&fetchCount,
			NULL,
			cql("SELECT typelem FROM pg_type "
				" WHERE oid = :1 ",
				ObjectIdGetDatum(arrayType)));

	if (!fetchCount)
		elog(ERROR, "cache lookup failed for type %u", arrayType);

	/* needn't check typisdefined since this will fail anyway */

	if (!OidIsValid(elementType))
		ereport(ERROR,
				(errcode(ERRCODE_DATATYPE_MISMATCH),
				 errmsg("cannot subscript type %s because it is not an array",
						format_type_be(arrayType))));

	return elementType;
}
Beispiel #25
0
/* 
 * Returns the dbid of the mirror. We can use the fact that
 * mirrors have the same contentid (stored in GpIdentity) and go from
 * there.
 */
int16
my_mirror_dbid(void)
{
	int16 dbid = 0;
	int16 contentid = (int16)GpIdentity.segindex;
	bool bOnly;
	HeapTuple tup;

	/*
	 * Can only run on a master node, this restriction is due to the reliance
	 * on the gp_segment_configuration table.  This may be able to be relaxed
	 * by switching to a different method of checking.
	 */
	if (GpIdentity.segindex != MASTER_CONTENT_ID)
		elog(ERROR, "my_mirror_dbid() executed on execution segment");

	tup = caql_getfirst_only(
			NULL,
			&bOnly,
			cql("SELECT dbid FROM gp_segment_configuration "
				" WHERE content = :1 "
				" AND role = :2 ",
				Int16GetDatum(contentid),
				CharGetDatum('m')));

	if (HeapTupleIsValid(tup))
	{
		dbid = ((Form_gp_segment_configuration) GETSTRUCT(tup))->dbid;
		/* We expect a single result, assert this */
		Assert(bOnly); /* should be only 1 */
	}
	/* no need to hold the lock, it's a catalog */

	return dbid;
}
/*
 * Tell the caller whether a standby master is defined in the system.
 */
static bool
standby_exists()
{
	return caql_getcount(
			 NULL,
			 cql("SELECT COUNT(*) FROM gp_segment_configuration "
				 " WHERE role = :1 ",
				 CharGetDatum(SEGMENT_ROLE_STANDBY_CONFIG))) > 0;
}
Beispiel #27
0
/*
 * GetFastSequences
 *
 * Get a list of consecutive sequence numbers. The starting sequence
 * number is the maximal value between 'lastsequence' + 1 and minSequence.
 * The length of the list is given.
 *
 * If there is not such an entry for objid in the table, create
 * one here.
 *
 * The existing entry for objid in the table is updated with a new
 * lastsequence value.
 */
int64 GetFastSequences(Oid objid, int64 objmod,
					   int64 minSequence, int64 numSequences)
{
	Relation gp_fastsequence_rel;
	TupleDesc tupleDesc;
	HeapTuple tuple;
	cqContext	 cqc;
	int64 firstSequence = minSequence;
	Datum lastSequenceDatum;
	int64 newLastSequence;

	gp_fastsequence_rel = heap_open(FastSequenceRelationId, RowExclusiveLock);
	tupleDesc = RelationGetDescr(gp_fastsequence_rel);
	
	tuple = caql_getfirst(
			caql_addrel(cqclr(&cqc), gp_fastsequence_rel),
			cql("SELECT * FROM gp_fastsequence "
				" WHERE objid = :1 "
				" AND objmod = :2 "
				" FOR UPDATE ",
				ObjectIdGetDatum(objid),
				Int64GetDatum(objmod)));

	if (!HeapTupleIsValid(tuple))
	{
		newLastSequence = firstSequence + numSequences - 1;
	}
	else
	{
		bool isNull;

		lastSequenceDatum = heap_getattr(tuple, Anum_gp_fastsequence_last_sequence,
										tupleDesc, &isNull);
		
		if (isNull)
			ereport(ERROR,
					(errcode(ERRCODE_UNDEFINED_OBJECT),
					 errmsg("got an invalid lastsequence number: NULL")));
		
		if (DatumGetInt64(lastSequenceDatum) + 1 > firstSequence)
			firstSequence = DatumGetInt64(lastSequenceDatum) + 1;
		newLastSequence = firstSequence + numSequences - 1;
	}
	
	update_fastsequence(gp_fastsequence_rel, tuple, tupleDesc,
						objid, objmod, newLastSequence);

	if (HeapTupleIsValid(tuple))
	{
		heap_freetuple(tuple);
	}
		
	/* Refer to the comment at the end of InsertFastSequenceEntry. */
	heap_close(gp_fastsequence_rel, RowExclusiveLock);

	return firstSequence;
}
Beispiel #28
0
/*
 * Add a master standby.
 *
 * gp_add_master_standby(hostname, address)
 *
 * Args:
 *  hostname - as above
 *  address - as above
 *
 * Returns:
 *  dbid of the new standby
 */
Datum
gp_add_master_standby(PG_FUNCTION_ARGS)
{
	CdbComponentDatabaseInfo *master = NULL;
	Relation	gprel;
	Datum values[Natts_gp_segment_configuration];
	bool nulls[Natts_gp_segment_configuration];
	HeapTuple tuple;
	cqContext	cqc;
	cqContext  *pcqCtx = NULL;

	if (PG_ARGISNULL(0))
		elog(ERROR, "host name cannot be NULL");
	if (PG_ARGISNULL(1))
		elog(ERROR, "address cannot be NULL");

	mirroring_sanity_check(MASTER_ONLY | UTILITY_MODE,
						   "gp_add_master_standby");

	if (standby_exists())
		elog(ERROR, "only a single master standby may be defined");

	/* master */
	master = registration_order_get_dbinfo(MASTER_ORDER_ID);

	/* Lock exclusively to avoid concurrent changes */
	gprel = heap_open(GpSegmentConfigRelationId, AccessExclusiveLock);

	pcqCtx = caql_beginscan(
				caql_addrel(cqclr(&cqc), gprel),
				cql("INSERT INTO gp_segment_configuration ", NULL));

	MemSet(nulls, false, sizeof(nulls));

	values[Anum_gp_segment_configuration_registration_order - 1] = Int32GetDatum(STANDBY_ORDER_ID);
	values[Anum_gp_segment_configuration_role - 1] = CharGetDatum(SEGMENT_ROLE_STANDBY_CONFIG);
	values[Anum_gp_segment_configuration_status - 1] = CharGetDatum('u');
	values[Anum_gp_segment_configuration_port - 1] = Int32GetDatum(master->port);
	values[Anum_gp_segment_configuration_hostname - 1] = PG_GETARG_DATUM(0);
	values[Anum_gp_segment_configuration_address - 1] = PG_GETARG_DATUM(1);
	nulls[Anum_gp_segment_configuration_description - 1] = true;

	tuple = caql_form_tuple(pcqCtx, values, nulls);

	/* insert a new tuple */
	caql_insert(pcqCtx, tuple); /* implicit update of index as well */

	caql_endscan(pcqCtx);

	if(master)
		pfree(master);

	heap_close(gprel, NoLock);

	PG_RETURN_INT16(1);
}
Beispiel #29
0
/*
 * Guts of rule deletion.
 */
void
RemoveRewriteRuleById(Oid ruleOid)
{
	cqContext  *pcqCtx;
	Relation	event_relation;
	HeapTuple	tuple;
	Oid			eventRelationOid;
	bool		hasMoreRules;

	/*
	 * Find the tuple for the target rule.
	 */
	pcqCtx = caql_beginscan(
			NULL,
			cql("SELECT * FROM pg_rewrite "
				" WHERE oid = :1 "
				" FOR UPDATE ",
				ObjectIdGetDatum(ruleOid)));

	tuple = caql_getnext(pcqCtx);

	if (!HeapTupleIsValid(tuple))
		elog(ERROR, "could not find tuple for rule %u", ruleOid);

	/*
	 * We had better grab AccessExclusiveLock so that we know no other rule
	 * additions/deletions are going on for this relation.	Else we cannot set
	 * relhasrules correctly.  Besides, we don't want to be changing the
	 * ruleset while queries are executing on the rel.
	 */
	eventRelationOid = ((Form_pg_rewrite) GETSTRUCT(tuple))->ev_class;
	event_relation = heap_open(eventRelationOid, AccessExclusiveLock);

	hasMoreRules = event_relation->rd_rules != NULL &&
		event_relation->rd_rules->numLocks > 1;

	/*
	 * Now delete the pg_rewrite tuple for the rule
	 */
	caql_delete_current(pcqCtx);

	caql_endscan(pcqCtx);


	/*
	 * Set pg_class 'relhasrules' field correctly for event relation.
	 *
	 * Important side effect: an SI notice is broadcast to force all backends
	 * (including me!) to update relcache entries with the new rule set.
	 * Therefore, must do this even if relhasrules is still true!
	 */
	SetRelationRuleStatus(eventRelationOid, hasMoreRules, false);

	/* Close rel, but keep lock till commit... */
	heap_close(event_relation, NoLock);
}
int main()
{
    CIMClient client;
    try
    {
      client.connectLocal();
    }
    catch (Exception& e)
    {
      PEGASUS_STD (cerr) << "Exception: " << e.getMessage()
                         << PEGASUS_STD (endl);
      PEGASUS_STD (cerr) << "connectLocal failed"
                         << PEGASUS_STD (endl);
      return -1;
    }

    String query1="SELECT MethodName FROM Test_IndicationProviderClass";

    // Note that CQL expects single quote around string literals,
    // while WQL expects double quote.
    // Note that CQL use <> for the inequality operator.
    String query2wql =
        "SELECT MethodName FROM Test_IndicationProviderClass "
            "WHERE IndicationIdentifier != \"x\"";
    String query2cql =
        "SELECT MethodName FROM Test_IndicationProviderClass "
            "WHERE IndicationIdentifier <> 'x'";

    String wql("WQL");
    String cql("DMTF:CQL");

    PEGASUS_STD (cout) << "+++++ start wql test" << PEGASUS_STD (endl);
    int rc;
    rc = _test(client, wql, query1, query2wql);
    if (rc != 0)
      return rc;
    PEGASUS_STD (cout) << "+++++ start dupliacte subscription test"
                       << PEGASUS_STD (endl);
    _testDuplicate(client);
    PEGASUS_STD (cout) << "+++++ duplicate subscription test completed"
                       << PEGASUS_STD (endl);

    PEGASUS_STD (cout) << "+++++ start concurrent subscription test"
                       << PEGASUS_STD (endl);
    _testConcurrent(client);
    PEGASUS_STD (cout) << "+++++ concurrent subscription test completed"
                       << PEGASUS_STD (endl);
#ifdef PEGASUS_ENABLE_CQL
    PEGASUS_STD (cout) << "+++++ start cql test" << PEGASUS_STD (endl);
    return _test(client, cql, query1, query2cql);
#else
    PEGASUS_STD (cout) << "+++++ cql test disabled" << PEGASUS_STD (endl);
    return 0;
#endif
}