예제 #1
0
파일: pg_paxos.c 프로젝트: godouxm/pg_paxos
/*
 * _PG_init is called when the module is loaded. In this function we save the
 * previous utility hook, and then install our hook to pre-intercept calls to
 * the copy command.
 */
void
_PG_init(void)
{
	PreviousExecutorStartHook = ExecutorStart_hook;
	ExecutorStart_hook = PgPaxosExecutorStart;

	PreviousProcessUtilityHook = ProcessUtility_hook;
	ProcessUtility_hook = PgPaxosProcessUtility;

	DefineCustomBoolVariable("pg_paxos.enabled",
							 "If enabled, pg_paxos handles queries on Paxos tables",
							 NULL, &PaxosEnabled, true, PGC_USERSET, 0, NULL, NULL,
							 NULL);

	DefineCustomStringVariable("pg_paxos.node_id",
							   "Unique node ID to use in Paxos interactions", NULL,
							   &PaxosNodeId, NULL, PGC_USERSET, 0, NULL,
							   NULL, NULL);

	DefineCustomEnumVariable("pg_paxos.consistency_model",
							 "Consistency model to use for reads (strong, optimistic)",
							 NULL, &ReadConsistencyModel, STRONG_CONSISTENCY,
							 consistency_model_options, PGC_USERSET, 0, NULL, NULL,
							 NULL);

	RegisterXactCallback(FinishPaxosTransaction, NULL);
}
/*
 * _PG_init()			- library load-time initialization
 *
 * DO NOT make this static nor change its name!
 */
void
_PG_init(void)
{
	/* Be sure we do initialization only once (should be redundant now) */
	static bool inited = false;

	if (inited)
		return;

	pg_bindtextdomain(TEXTDOMAIN);

	DefineCustomEnumVariable("plpgsql.variable_conflict",
							 gettext_noop("Sets handling of conflicts between PL/pgSQL variable names and table column names."),
							 NULL,
							 &plpgsql_variable_conflict,
							 PLPGSQL_RESOLVE_ERROR,
							 variable_conflict_options,
							 PGC_SUSET, 0,
							 NULL, NULL, NULL);

	EmitWarningsOnPlaceholders("plpgsql");

	plpgsql_HashTableInit();
	RegisterXactCallback(plpgsql_xact_cb, NULL);
	RegisterSubXactCallback(plpgsql_subxact_cb, NULL);

	/* Set up a rendezvous point with optional instrumentation plugin */
	plugin_ptr = (PLpgSQL_plugin **) find_rendezvous_variable("PLpgSQL_plugin");

	inited = true;
}
예제 #3
0
파일: pllua.c 프로젝트: eugwne/pllua
Datum _PG_init(PG_FUNCTION_ARGS) {
  init_vmstructs();
  pllua_init_common_ctx();
  LuaVM[0] = luaP_newstate(0); /* untrusted */
  LuaVM[1] = luaP_newstate(1); /* trusted */
  RegisterXactCallback(pllua_xact_cb, NULL);
  PG_RETURN_VOID();
}
예제 #4
0
파일: kt_fdw.c 프로젝트: gugu/kt_fdw
 KTDB * GetKtConnection(struct ktTableOptions *table_options)
 {
   bool        found;
    KtConnCacheEntry *entry;
    KtConnCacheKey key;

    /* First time through, initialize connection cache hashtable */
    if (ConnectionHash == NULL)
    {
        HASHCTL     ctl;

        MemSet(&ctl, 0, sizeof(ctl));
        ctl.keysize = sizeof(KtConnCacheKey);
        ctl.entrysize = sizeof(KtConnCacheEntry);
        ctl.hash = tag_hash;
        /* allocate ConnectionHash in the cache context */
        ctl.hcxt = CacheMemoryContext;
        ConnectionHash = hash_create("kt_fdw connections", 8,
                                     &ctl,
                                   HASH_ELEM | HASH_FUNCTION | HASH_CONTEXT);

#ifdef USE_TRANSACTIONS
        RegisterXactCallback(ktSubXactCallback, NULL);
#endif
    }

    /* Create hash key for the entry.  Assume no pad bytes in key struct */
    key.serverId = table_options->serverId;
    key.userId = table_options->userId;

    /*
     * Find or create cached entry for requested connection.
     */
    entry = hash_search(ConnectionHash, &key, HASH_ENTER, &found);
    if (!found)
    {
        /* initialize new hashtable entry (key is already filled in) */
        entry->db = NULL;
        entry->xact_depth = 0;
    }

    if (entry->db == NULL)
    {
        entry->db = ktdbnew();

        if(!entry->db)
            elog(ERROR, "could not allocate memory for ktdb");

        if(!ktdbopen(entry->db, table_options->host, table_options->port, table_options->timeout))
            elog(ERROR,"Could not open connection to KT %s %s", ktgeterror(entry->db), ktgeterrormsg(entry->db));
    }

#ifdef USE_TRANSACTIONS
    KtBeginTransactionIfNeeded(entry);
#endif

    return entry->db;
 }
예제 #5
0
static void DtmInitialize()
{
	bool found;
	static HASHCTL info;

	LWLockAcquire(AddinShmemInitLock, LW_EXCLUSIVE);
	dtm = ShmemInitStruct("dtm", sizeof(DtmState), &found);
	if (!found)
	{
		dtm->hashLock = LWLockAssign();
		dtm->xidLock = LWLockAssign();
		dtm->nReservedXids = 0;
		dtm->minXid = InvalidTransactionId;
        dtm->nNodes = MMNodes;
		dtm->disabledNodeMask = 0;
        pg_atomic_write_u32(&dtm->nReceivers, 0);
        dtm->initialized = false;
        BgwPoolInit(&dtm->pool, MMExecutor, MMDatabaseName, MMQueueSize);
		RegisterXactCallback(DtmXactCallback, NULL);
		RegisterSubXactCallback(DtmSubXactCallback, NULL);
	}
	LWLockRelease(AddinShmemInitLock);

	info.keysize = sizeof(TransactionId);
	info.entrysize = sizeof(TransactionId);
	info.hash = dtm_xid_hash_fn;
	info.match = dtm_xid_match_fn;
	xid_in_doubt = ShmemInitHash(
		"xid_in_doubt",
		DTM_HASH_SIZE, DTM_HASH_SIZE,
		&info,
		HASH_ELEM | HASH_FUNCTION | HASH_COMPARE
	);

	info.keysize = sizeof(TransactionId);
	info.entrysize = sizeof(LocalTransaction);
	info.hash = dtm_xid_hash_fn;
	info.match = dtm_xid_match_fn;
	local_trans = ShmemInitHash(
		"local_trans",
		DTM_HASH_SIZE, DTM_HASH_SIZE,
		&info,
		HASH_ELEM | HASH_FUNCTION | HASH_COMPARE
	);

    MMDoReplication = true;
	TM = &DtmTM;
}
예제 #6
0
/*
 * _PG_init()			- library load-time initialization
 *
 * DO NOT make this static nor change its name!
 */
void
_PG_init(void)
{
	/* Be sure we do initialization only once (should be redundant now) */
	static bool inited = false;

	if (inited)
		return;

	plpgsql_HashTableInit();
	RegisterXactCallback(plpgsql_xact_cb, NULL);
	RegisterSubXactCallback(plpgsql_subxact_cb, NULL);

	/* Set up a rendezvous point with optional instrumentation plugin */
	plugin_ptr = (PLpgSQL_plugin **) find_rendezvous_variable("PLpgSQL_plugin");

	inited = true;
}
예제 #7
0
void
_PG_init()
{
	HASHCTL		ctl;
	MemoryContext oldctx = MemoryContextSwitchTo(CacheMemoryContext);

	Py_Initialize();
	RegisterXactCallback(multicorn_xact_callback, NULL);
#if PG_VERSION_NUM >= 90300
	RegisterSubXactCallback(multicorn_subxact_callback, NULL);
#endif
	/* Initialize the global oid -> python instances hash */
	MemSet(&ctl, 0, sizeof(ctl));
	ctl.keysize = sizeof(Oid);
	ctl.entrysize = sizeof(CacheEntry);
	ctl.hash = oid_hash;
	ctl.hcxt = CacheMemoryContext;
	InstancesHash = hash_create("multicorn instances", 32,
								&ctl,
								HASH_ELEM | HASH_FUNCTION);
	MemoryContextSwitchTo(oldctx);
}
예제 #8
0
void
start_transaction(PlxConn *plx_conn)
{
    int        curlevel;
    StringInfo sql = NULL;

    if (!strcmp(plx_conn->plx_cluster->isolation_level, "auto commit"))
        return;

    curlevel = GetCurrentTransactionNestLevel();
    if (!is_remote_transaction)
    {
        RegisterXactCallback(xact_callback, NULL);
        RegisterSubXactCallback(subxact_callback, NULL);
        is_remote_transaction = true;
    }

    if (plx_conn->xlevel == 0)
    {
        sql = makeStringInfo();
        appendStringInfo(sql,
                         "start transaction isolation level %s;",
                         plx_conn->plx_cluster->isolation_level);
        plx_conn->xlevel = 1;
    }

    while (plx_conn->xlevel < curlevel)
    {
        if (!sql)
            sql = makeStringInfo();
        appendStringInfo(sql, "savepoint s%d; ", (int) ++(plx_conn->xlevel));
        is_remote_subtransaction = true;
    }
    if (sql)
        PQclear(PQexec(plx_conn->pq_conn, sql->data));
}
예제 #9
0
/*
 * Get a PGconn which can be used to execute queries on the remote PostgreSQL
 * server with the user's authorization.  A new connection is established
 * if we don't already have a suitable one, and a transaction is opened at
 * the right subtransaction nesting depth if we didn't do that already.
 *
 * will_prep_stmt must be true if caller intends to create any prepared
 * statements.	Since those don't go away automatically at transaction end
 * (not even on error), we need this flag to cue manual cleanup.
 *
 * XXX Note that caching connections theoretically requires a mechanism to
 * detect change of FDW objects to invalidate already established connections.
 * We could manage that by watching for invalidation events on the relevant
 * syscaches.  For the moment, though, it's not clear that this would really
 * be useful and not mere pedantry.  We could not flush any active connections
 * mid-transaction anyway.
 */
PGconn *
GetConnection(ForeignServer *server, UserMapping *user,
			  bool will_prep_stmt)
{
	bool		found;
	ConnCacheEntry *entry;
	ConnCacheKey key;

	/* First time through, initialize connection cache hashtable */
	if (ConnectionHash == NULL)
	{
		HASHCTL		ctl;

		MemSet(&ctl, 0, sizeof(ctl));
		ctl.keysize = sizeof(ConnCacheKey);
		ctl.entrysize = sizeof(ConnCacheEntry);
		ctl.hash = tag_hash;
		/* allocate ConnectionHash in the cache context */
		ctl.hcxt = CacheMemoryContext;
		ConnectionHash = hash_create("postgres_fdw connections", 8,
									 &ctl,
								   HASH_ELEM | HASH_FUNCTION | HASH_CONTEXT);

		/*
		 * Register some callback functions that manage connection cleanup.
		 * This should be done just once in each backend.
		 */
		RegisterXactCallback(pgfdw_xact_callback, NULL);
		RegisterSubXactCallback(pgfdw_subxact_callback, NULL);
	}

	/* Set flag that we did GetConnection during the current transaction */
	xact_got_connection = true;

	/* Create hash key for the entry.  Assume no pad bytes in key struct */
	key.serverid = server->serverid;
	key.userid = user->userid;

	/*
	 * Find or create cached entry for requested connection.
	 */
	entry = hash_search(ConnectionHash, &key, HASH_ENTER, &found);
	if (!found)
	{
		/* initialize new hashtable entry (key is already filled in) */
		entry->conn = NULL;
		entry->xact_depth = 0;
		entry->have_prep_stmt = false;
		entry->have_error = false;
	}

	/*
	 * We don't check the health of cached connection here, because it would
	 * require some overhead.  Broken connection will be detected when the
	 * connection is actually used.
	 */

	/*
	 * If cache entry doesn't have a connection, we have to establish a new
	 * connection.	(If connect_pg_server throws an error, the cache entry
	 * will be left in a valid empty state.)
	 */
	if (entry->conn == NULL)
	{
		entry->xact_depth = 0;	/* just to be sure */
		entry->have_prep_stmt = false;
		entry->have_error = false;
		entry->conn = connect_pg_server(server, user);
		elog(DEBUG3, "new postgres_fdw connection %p for server \"%s\"",
			 entry->conn, server->servername);
	}

	/*
	 * Start a new transaction or subtransaction if needed.
	 */
	begin_remote_xact(entry);

	/* Remember if caller will prepare statements */
	entry->have_prep_stmt |= will_prep_stmt;

	return entry->conn;
}
예제 #10
0
void _PG_init() {
  RegisterXactCallback(amqp_local_phase2, NULL);
}