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)); }
/* * 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); }
/* * 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; }
/* * 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; }
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)); }
/* * 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); }
/* * 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 */
/* * 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; }
/* * 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); }
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); }
/* * 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; }
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; }
/* * 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 */
/* * 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); } }
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; }
/* 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 */
/* * 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; }
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); }
/* * 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; }
/* * 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; }
/* * 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; }
/* * 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); }
/* * 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 }