/* * GetOrEstablishConnection returns a PGconn which can be used to execute * queries on a remote PostgreSQL server. If no suitable connection to the * specified node on the specified port yet exists, the function establishes * a new connection and adds it to the connection cache before returning it. * * Returned connections are guaranteed to be in the CONNECTION_OK state. If the * requested connection cannot be established, or if it was previously created * but is now in an unrecoverable bad state, this function returns NULL. * * This function throws an error if a hostname over 255 characters is provided. */ PGconn * GetOrEstablishConnection(char *nodeName, int32 nodePort) { PGconn *connection = NULL; NodeConnectionKey nodeConnectionKey; NodeConnectionEntry *nodeConnectionEntry = NULL; bool entryFound = false; bool needNewConnection = true; char *userName = CurrentUserName(); /* check input */ if (strnlen(nodeName, MAX_NODE_LENGTH + 1) > MAX_NODE_LENGTH) { ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("hostname exceeds the maximum length of %d", MAX_NODE_LENGTH))); } /* if first call, initialize the connection hash */ if (NodeConnectionHash == NULL) { NodeConnectionHash = CreateNodeConnectionHash(); } memset(&nodeConnectionKey, 0, sizeof(nodeConnectionKey)); strncpy(nodeConnectionKey.nodeName, nodeName, MAX_NODE_LENGTH); nodeConnectionKey.nodePort = nodePort; strncpy(nodeConnectionKey.nodeUser, userName, NAMEDATALEN); nodeConnectionEntry = hash_search(NodeConnectionHash, &nodeConnectionKey, HASH_FIND, &entryFound); if (entryFound) { connection = nodeConnectionEntry->connection; if (PQstatus(connection) == CONNECTION_OK) { needNewConnection = false; } else { PurgeConnection(connection); } } if (needNewConnection) { connection = ConnectToNode(nodeName, nodePort, nodeConnectionKey.nodeUser); if (connection != NULL) { nodeConnectionEntry = hash_search(NodeConnectionHash, &nodeConnectionKey, HASH_ENTER, &entryFound); nodeConnectionEntry->connection = connection; } } return connection; }
/* * GetConnection returns a PGconn which can be used to execute queries on a * remote PostgreSQL server. If no suitable connection to the specified node on * the specified port yet exists, the function establishes a new connection and * returns that. * * Returned connections are guaranteed to be in the CONNECTION_OK state. If the * requested connection cannot be established, or if it was previously created * but is now in an unrecoverable bad state, this function returns NULL. * * This function throws an error if a hostname over 255 characters is provided. */ PGconn * GetConnection(char *nodeName, int32 nodePort) { PGconn *connection = NULL; NodeConnectionKey nodeConnectionKey; NodeConnectionEntry *nodeConnectionEntry = NULL; bool entryFound = false; bool needNewConnection = true; /* check input */ if (strnlen(nodeName, MAX_NODE_LENGTH + 1) > MAX_NODE_LENGTH) { ereport(ERROR, (errmsg("hostnames may not exceed 255 characters"))); } /* if first call, initialize the connection hash */ if (NodeConnectionHash == NULL) { NodeConnectionHash = CreateNodeConnectionHash(); } memset(&nodeConnectionKey, 0, sizeof(nodeConnectionKey)); strncpy(nodeConnectionKey.nodeName, nodeName, MAX_NODE_LENGTH); nodeConnectionKey.nodePort = nodePort; nodeConnectionEntry = hash_search(NodeConnectionHash, &nodeConnectionKey, HASH_FIND, &entryFound); if (entryFound) { connection = nodeConnectionEntry->connection; if (PQstatus(connection) == CONNECTION_OK) { needNewConnection = false; } else { PurgeConnection(connection); } } if (needNewConnection) { StringInfo nodePortString = makeStringInfo(); appendStringInfo(nodePortString, "%d", nodePort); connection = ConnectToNode(nodeName, nodePortString->data); if (connection != NULL) { nodeConnectionEntry = hash_search(NodeConnectionHash, &nodeConnectionKey, HASH_ENTER, &entryFound); nodeConnectionEntry->connection = connection; } } return connection; }