blob: b74ce13a026002bc893beb95f53d181752876fea [file] [log] [blame]
/*-------------------------------------------------------------------------
*
* cdb_table.c
*
* Structures and functions to read cdb tables using libpq.
*
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
*-------------------------------------------------------------------------
*/
#include "postgres_fe.h"
#include "pqexpbuffer.h"
#include "libpq-fe.h"
#include "cdb_dump_util.h"
#include "cdb_table.h"
/*-------------------------------------------------------------------------
*
* FreeCDBAssignmentArray( CDBAssignmentArray* pAssignmentAr ) returns void
*
* This frees the pointers allocated in each of the CDBAssignment structs
* that are part of the pAssignmentAr->pData array, and then frees the pData
* pointer itself. It does NOT free the pAssignmentAr.
*-------------------------------------------------------------------------
*/
/*
void FreeCDBAssignmentArray( CDBAssignmentArray* pAssignmentAr )
{
if ( pAssignmentAr == NULL )
return;
int i;
for ( i=0; i<pAssignmentAr->count; i++ )
{
CDBAssignment* pAssignment = &pAssignmentAr->pData[i];
if ( pAssignment->pszTableName != NULL )
free( pAssignment->pszTableName );
if ( pAssignment->pszNspName != NULL )
free( pAssignment->pszNspName );
}
if ( pAssignmentAr->pData != NULL )
{
free( pAssignmentAr->pData );
pAssignmentAr->pData = NULL;
}
pAssignmentAr->count = 0;
}
*/
/*-------------------------------------------------------------------------
*
* FreeCDBBaseTableArray( CDBBaseTableArray* pTableAr ) returns void
*
* This frees the pointers allocated in each of the CBBBaseTable structs
* that are part of the pTableAr->pData array, and then frees the pData
* pointer itself. It does NOT free the pTableAr.
*-------------------------------------------------------------------------
*/
void
FreeCDBBaseTableArray(CDBBaseTableArray *pTableAr)
{
int i;
if (pTableAr == NULL)
return;
for (i = 0; i < pTableAr->count; i++)
{
CDBBaseTable *pBaseTable = &pTableAr->pData[i];
if (pBaseTable->pszTableName != NULL)
free(pBaseTable->pszTableName);
if (pBaseTable->pszNspName != NULL)
free(pBaseTable->pszNspName);
}
if (pTableAr->pData != NULL)
free(pTableAr->pData);
pTableAr->count = 0;
pTableAr->pData = NULL;
}
/*-------------------------------------------------------------------------
*
* FreeCDBInstanceArray( CDBInstanceArray* pInstanceAr ) returns void
*
* This frees the pointers allocated in each of the CBBInstance structs
* that are part of the pInstanceAr->pData array, and then frees the pData
* pointer itself. It does NOT free the pInstanceAr.
*-------------------------------------------------------------------------
*/
/*
void FreeCDBInstanceArray( CDBInstanceArray* pInstanceAr )
{
if ( pInstanceAr == NULL )
return;
int i;
for ( i=0; i<pInstanceAr->count; i++ )
{
CDBInstance* pInstance = &pInstanceAr->pData[i];
if ( pInstance->pszHost != NULL )
free( pInstance->pszHost );
if ( pInstance->pszDataDir != NULL )
free( pInstance->pszDataDir );
}
if ( pInstanceAr->pData != NULL )
{
free( pInstanceAr->pData );
pInstanceAr->pData = NULL;
}
pInstanceAr->count = 0;
}
*/
/*-------------------------------------------------------------------------
*
* FreeCDBPolicyArray( CDBPolicyArray* pPolicyAr ) returns void
*
* This frees the pointers allocated in each of the CDBPolicy structs
* that are part of the pPolicyAr->pData array, and then frees the pData
* pointer itself. It does NOT free the pPolicyAr.
*-------------------------------------------------------------------------
*/
/*
void FreeCDBPolicyArray( CDBPolicyArray* pPolicyAr )
{
if ( pPolicyAr == NULL )
return;
int i;
for ( i=0; i<pPolicyAr->count; i++ )
{
CDBPolicy* pPolicy = &pPolicyAr->pData[i];
if ( pPolicy->pszTableName != NULL )
free( pPolicy->pszTableName );
if ( pPolicy->pszNspName != NULL )
free( pPolicy->pszNspName );
if ( pPolicy->pszParameters != NULL )
free( pPolicy->pszParameters );
}
if ( pPolicyAr->pData != NULL )
{
free( pPolicyAr->pData );
pPolicyAr->pData = NULL;
}
pPolicyAr->count = 0;
}
*/
/*-------------------------------------------------------------------------
*
* FreeCDBSegArray( CDBSegArray* pSegAr ) returns void
*
* This frees the pointers allocated in each of the CDVSeg structs
* that are part of the pSegAr->pData array, and then frees the pData
* pointer itself. It does NOT free the pSegAr.
*-------------------------------------------------------------------------
*/
/*
void FreeCDBSegArray( CDBSegArray* pSegAr )
{
if ( pSegAr == NULL )
return;
int i;
for ( i=0; i<pSegAr->count; i++ )
{
CDBSeg* pSeg = &pSegAr->pData[i];
if ( pSeg->pszDBName != NULL )
free( pSeg->pszDBName );
if ( pSeg->pszDBUser != NULL )
free( pSeg->pszDBUser );
if ( pSeg->pszDBPswd != NULL )
free( pSeg->pszDBPswd );
}
if ( pSegAr->pData != NULL )
{
free( pSegAr->pData );
pSegAr->pData = NULL;
}
pSegAr->count = 0;
}
*/
/*-------------------------------------------------------------------------
*
* FreeCDBSegmentInstanceArray( CDBSegmentInstanceArray* pSegmentInstanceAr ) returns void
*
* This frees the pointers allocated in each of the CDBSegmentInstance structs
* that are part of the pSegmentInstanceAr->pData array, and then frees the pData
* pointer itself. It does NOT free the pSegmentInstanceAr.
*-------------------------------------------------------------------------
*/
void
FreeCDBSegmentInstanceArray(CDBSegmentInstanceArray *pSegmentInstanceAr)
{
if (pSegmentInstanceAr == NULL)
return;
if (pSegmentInstanceAr->pData != NULL)
{
free(pSegmentInstanceAr->pData);
pSegmentInstanceAr->pData = NULL;
}
pSegmentInstanceAr->count = 0;
}
/*-------------------------------------------------------------------------
*
* GetCDBAssignmentArray(PGconn* pConn, const char* pszDBName, CDBAssignmentArray* pAssignmentAr )
* returns bool
*
* This reads all rows from cdb_assignment,
* joining with pg_class and pg_namespace to get the table and schema names.
*
* After using it, call FreeCDBAssignmentArray.
*-------------------------------------------------------------------------
*/
/*
bool GetCDBAssignmentArray(PGconn* pConn, const char* pszDBName, CDBAssignmentArray* pAssignmentAr )
{
bool bRtn = false;
PQExpBuffer pQry = NULL;
PGresult* pRes = NULL;
pAssignmentAr->count = 0;
pAssignmentAr->pData = NULL;
pQry = createPQExpBuffer();
appendPQExpBuffer(pQry, " SELECT"
" a.tbloid,"
" c.relname,"
" n.nspname,"
" a.partno,"
" a.segid"
" FROM"
" cdb_assignment a,"
" pg_class c,"
" pg_namespace n"
" WHERE"
" a.tbloid = c.oid"
" AND c.relnamespace = n.oid"
" ORDER BY"
" 2" );
pRes = PQexec(pConn, pQry->data);
if ( pRes == NULL || PQresultStatus(pRes) != PGRES_TUPLES_OK )
{
write_err_msg("query to obtain list of cdb assignments failed : %s",
PQerrorMessage(pConn));
goto cleanup;
}
int ntups = PQntuples(pRes);
if (ntups <= 0)
{
write_err_msg("no CDB assignments for database \"%s\"\n", pszDBName);
goto cleanup;
}
pAssignmentAr->count = ntups;
pAssignmentAr->pData = (CDBAssignment *)calloc( ntups, sizeof(CDBAssignment) );
if ( pAssignmentAr->pData == NULL )
{
write_err_msg("cannot allocate memory for query results in GetCDBAssignmentArray\n");
goto cleanup;
}
int i_tbloid = PQfnumber(pRes, "tbloid");
int i_relname = PQfnumber(pRes, "relname");
int i_nspname = PQfnumber(pRes, "nspname");
int i_partno = PQfnumber(pRes, "partno");
int i_dbid = PQfnumber(pRes, "segid");
int i;
for ( i=0; i<ntups; i++ )
{
CDBAssignment* pAssignment = &pAssignmentAr->pData[i];
pAssignment->tbloid = atoi(PQgetvalue(pRes, i, i_tbloid));
pAssignment->pszTableName = strdup(PQgetvalue(pRes, i, i_relname));
pAssignment->pszNspName = strdup(PQgetvalue(pRes, i, i_nspname));
pAssignment->partno = atoi(PQgetvalue(pRes, i, i_partno));
pAssignment->segid = atoi(PQgetvalue(pRes, i, i_dbid));
}
bRtn = true;
cleanup:
if ( pRes != NULL )
PQclear(pRes);
if ( pQry != NULL )
destroyPQExpBuffer(pQry);
return bRtn;
}
*/
/*-------------------------------------------------------------------------
*
* GetCDBBaseTableArray(PGconn* pConn, const char* pszDBName, CDBBaseTableArray* pTableAr )
* returns bool
*
* This reads all rows from cdb_basetable, with an optional filter on partitioned.
*
* After using it, call FreeCDBBaseTableArray.
*-------------------------------------------------------------------------
*/
bool
GetCDBBaseTableArray(PGconn *pConn, CDBBaseTableArray *pTableAr)
{
bool bRtn = false;
PQExpBuffer pQry = NULL;
PGresult *pRes = NULL;
int ntups;
int i_tbloid;
int i_relname;
int i_nspname;
int i;
pTableAr->count = 0;
pTableAr->pData = NULL;
pQry = createPQExpBuffer();
appendPQExpBuffer(pQry, " SELECT"
" p.localoid,"
" c.relname,"
" n.nspname"
" FROM"
" gp_distribution_policy p,"
" pg_class c,"
" pg_namespace n"
" WHERE"
" p.localoid = c.oid"
" AND c.relnamespace = n.oid"
" AND NOT c.relkind = 'x'"
" ORDER BY"
" 2");
pRes = PQexec(pConn, pQry->data);
if (pRes == NULL || PQresultStatus(pRes) != PGRES_TUPLES_OK)
{
mpp_err_msg("ERROR", "mpp_table", "query to obtain list of Greenplum managed tables failed : %s",
PQerrorMessage(pConn));
goto cleanup;
}
ntups = PQntuples(pRes);
/*
if (ntups <= 0)
{
write_err_msg("no Greenplum managed tables for database \"%s\"\n", pszDBName);
goto cleanup;
}
*/
pTableAr->count = ntups;
pTableAr->pData = (CDBBaseTable *) calloc(ntups, sizeof(CDBBaseTable));
if (pTableAr->pData == NULL)
{
mpp_err_msg("ERROR", "mpp_table", "cannot allocate memory for query results in GetCDBBaseTableArray\n");
goto cleanup;
}
/* get column numbers */
i_tbloid = PQfnumber(pRes, "localoid");
i_relname = PQfnumber(pRes, "relname");
i_nspname = PQfnumber(pRes, "nspname");
for (i = 0; i < ntups; i++)
{
CDBBaseTable *pBaseTable = &pTableAr->pData[i];
pBaseTable->tbloid = atoi(PQgetvalue(pRes, i, i_tbloid));
pBaseTable->pszTableName = strdup(PQgetvalue(pRes, i, i_relname));
pBaseTable->pszNspName = strdup(PQgetvalue(pRes, i, i_nspname));
}
bRtn = true;
cleanup:
if (pRes != NULL)
PQclear(pRes);
if (pQry != NULL)
destroyPQExpBuffer(pQry);
return bRtn;
}
/*-------------------------------------------------------------------------
*
* GetCDBSegmentInstanceArray(PGconn* pConn, const char* pszDBName, CDBSegmentInstanceArray* pSegmentInstanceAr )
* returns bool
*
* This reads all rows from gp_segment_instance.
*
* After using it, call FreeCDBSegmentInstanceArray.
*-------------------------------------------------------------------------
*/
bool
GetCDBSegmentInstanceArray(PGconn *pConn, const char *pszDBName, CDBSegmentInstanceArray *pSegmentInstanceAr)
{
int ntups;
int i_dbid;
int i_isValid;
int i_hostname;
int i_port;
int i_datadir;
int i;
bool bRtn = false;
PQExpBuffer pQry = NULL;
PGresult *pRes = NULL;
pSegmentInstanceAr->count = 0;
pSegmentInstanceAr->pData = NULL;
pQry = createPQExpBuffer();
appendPQExpBuffer(pQry, " SELECT"
" d.dbid,"
" d.valid,"
" h.hostname,"
" l.port,"
" l.datadir"
" FROM"
" mpp.pgdatabase d,"
" mpp.listener l,"
" mpp.host h"
" where d.listenerid = l.listenerid"
" and l.hostId = h.hostid");
pRes = PQexec(pConn, pQry->data);
if (pRes == NULL || PQresultStatus(pRes) != PGRES_TUPLES_OK)
{
mpp_err_msg("ERROR", "mpp_table" "query to obtain list of Greenplum segment databases failed : %s",
PQerrorMessage(pConn));
goto cleanup;
}
ntups = PQntuples(pRes);
if (ntups <= 0)
{
mpp_err_msg("ERROR", "mpp_table" "no Greenplum segment databases for database \"%s\"\n", pszDBName);
goto cleanup;
}
pSegmentInstanceAr->count = ntups;
pSegmentInstanceAr->pData = (CDBSegmentInstance *) malloc(ntups * sizeof(CDBSegmentInstance));
if (pSegmentInstanceAr->pData == NULL)
{
mpp_err_msg("ERROR", "mpp_table", "cannot allocate memory for query results in GetCDBSegmentInstanceArray\n");
goto cleanup;
}
i_dbid = PQfnumber(pRes, "dbid");
i_isValid = PQfnumber(pRes, "valid");
i_hostname = PQfnumber(pRes, "hostname");
i_port = PQfnumber(pRes, "port");
i_datadir = PQfnumber(pRes, "datadir");
for (i = 0; i < ntups; i++)
{
CDBSegmentInstance *pSegmentInstance = &pSegmentInstanceAr->pData[i];
pSegmentInstance->segid = atoi(PQgetvalue(pRes, i, i_dbid));
pSegmentInstance->isValid = (strcmp(PQgetvalue(pRes, i, i_isValid), "t") == 0);
pSegmentInstance->dbname = strdup(pszDBName);
pSegmentInstance->dbhostname = PQgetvalue(pRes, i, i_hostname);
pSegmentInstance->dbport = atoi(PQgetvalue(pRes, i, i_port));
pSegmentInstance->dbdatadir = PQgetvalue(pRes, i, i_datadir);
}
bRtn = true;
cleanup:
if (pRes != NULL)
PQclear(pRes);
if (pQry != NULL)
destroyPQExpBuffer(pQry);
return bRtn;
}