You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hawq.apache.org by od...@apache.org on 2016/11/21 19:14:39 UTC
incubator-hawq git commit: HAWQ-1130. Make HCatalog integration work
with non-superusers.
Repository: incubator-hawq
Updated Branches:
refs/heads/master 38b447d7e -> 475dbb5cb
HAWQ-1130. Make HCatalog integration work with non-superusers.
Project: http://git-wip-us.apache.org/repos/asf/incubator-hawq/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-hawq/commit/475dbb5c
Tree: http://git-wip-us.apache.org/repos/asf/incubator-hawq/tree/475dbb5c
Diff: http://git-wip-us.apache.org/repos/asf/incubator-hawq/diff/475dbb5c
Branch: refs/heads/master
Commit: 475dbb5cb264177199a9722ca2f0b7f2c8c6743b
Parents: 38b447d
Author: Oleksandr Diachenko <od...@pivotal.io>
Authored: Mon Nov 21 11:14:01 2016 -0800
Committer: Oleksandr Diachenko <od...@pivotal.io>
Committed: Mon Nov 21 11:14:01 2016 -0800
----------------------------------------------------------------------
src/backend/access/transam/varsup.c | 143 ++++++++++++++++++++++---------
1 file changed, 103 insertions(+), 40 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/475dbb5c/src/backend/access/transam/varsup.c
----------------------------------------------------------------------
diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index fadefd5..73a4769 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -16,6 +16,7 @@
#include "access/clog.h"
#include "access/subtrans.h"
#include "access/transam.h"
+#include "catalog/catquery.h"
#include "executor/spi.h"
#include "miscadmin.h"
#include "postmaster/autovacuum.h"
@@ -408,6 +409,9 @@ GetNewExternalObjectId(void)
/*
* must perform check on External Oid range on
* initial access of NextExternalOid
+ *
+ * It's needed for upgrade scenario from old version
+ * of HAWQ which doesn't support dedicated oid pool for HCatalog objects
*/
if (!IsExternalOidInitialized)
{
@@ -416,6 +420,11 @@ GetNewExternalObjectId(void)
ResetExternalObjectId();
}
+ /*
+ * This check is needed for upgrade from old HAWQ versions, which don't support
+ * oid pool for HCatalog objects.
+ * In current implementation max oid will be always less than FirstExternalObjectId.
+ */
if (!IsValidExternalOidRange)
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_RESOURCES),
@@ -474,74 +483,128 @@ ResetExternalObjectId(void)
/*
* master_highest_used_oid
- * Query the database to find the highest used Oid by
+ * Uses CAQL and SPI to find the highest used Oid among user and catalog tables
+ *
+ * Uses CAQL to query catalog tables
+ * Uses SPI to query user tables, because CAQL supports tables from CatCoreRelation array only
* 1) Find all the relations that has Oids
* 2) Find max oid from those relations
*/
Oid
master_highest_used_oid(void)
{
+ Oid oidMaxCatalog = InvalidOid;
+ Oid oidMaxUser = InvalidOid;
Oid oidMax = InvalidOid;
+ Oid currentOid;
+ Form_pg_class classForm;
+ cqContext *pcqOuterCtx;
+ cqContext *pcqInnerCtx;
+ HeapTuple outerTuple;
+ HeapTuple innerTuple;
+ /* number of user tables having oids*/
+ int userTablesNum = 0;
+ int ret;
+
+ pcqOuterCtx = caql_beginscan(NULL, cql("SELECT * FROM pg_class WHERE relhasoids = :1", BoolGetDatum(true)));
- if (SPI_OK_CONNECT != SPI_connect())
+ outerTuple = caql_getnext(pcqOuterCtx);
+
+ if (!HeapTupleIsValid(outerTuple))
{
- ereport(ERROR, (errcode(ERRCODE_CDB_INTERNAL_ERROR),
- errmsg("Unable to connect to execute internal query for HCatalog.")));
+ caql_endscan(pcqOuterCtx);
+ elog(DEBUG1, "Unable to get list of tables having oids");
+ return oidMax;
}
- int ret = SPI_execute("SELECT relname FROM pg_class where relhasoids=true", true, 0);
+ /* construct query to get max oid from all tables with oids */
+ StringInfo sqlstrCatalog = makeStringInfo();
+ StringInfo sqlstrUser = makeStringInfo();
+ appendStringInfo(sqlstrUser, "SELECT max(oid) FROM (");
+ while (HeapTupleIsValid(outerTuple))
+ {
+ classForm = (Form_pg_class) GETSTRUCT(outerTuple);
- int rows = SPI_processed;
+ /* use CAQL for accessing catalog tables*/
+ if (classForm->relnamespace == PG_CATALOG_NAMESPACE)
+ {
+ appendStringInfo(sqlstrCatalog,
+ "SELECT oid FROM %s WHERE oid > :1 ORDER BY oid",
+ classForm->relname.data);
- char *tableNames[rows];
+ pcqInnerCtx = caql_beginscan(NULL,
+ cql1(sqlstrCatalog->data, __FILE__, __LINE__,
+ ObjectIdGetDatum(oidMaxCatalog)));
- if (rows == 0 || ret <= 0 || NULL == SPI_tuptable)
- {
- SPI_finish();
- return oidMax;
- }
+ innerTuple = caql_getnext(pcqInnerCtx);
- TupleDesc tupdesc = SPI_tuptable->tupdesc;
- SPITupleTable *tuptable = SPI_tuptable;
+ currentOid = InvalidOid;
- for (int i = 0; i < rows; i++)
- {
- HeapTuple tuple = tuptable->vals[i];
- tableNames[i] = SPI_getvalue(tuple, tupdesc, 1);
- }
+ while (HeapTupleIsValid(innerTuple))
+ {
+ currentOid = HeapTupleGetOid(innerTuple);
+ innerTuple = caql_getnext(pcqInnerCtx);
+ }
- /* construct query to get max oid from all tables with oids */
- StringInfoData sqlstr;
- initStringInfo(&sqlstr);
- appendStringInfo(&sqlstr, "SELECT max(oid) FROM (");
- for (int i = 0; i < rows; i++)
- {
- if (i > 0)
+ elog(DEBUG1, "Max Oid in catalog table %s: %d", classForm->relname.data, currentOid);
+
+ caql_endscan(pcqInnerCtx);
+
+ oidMaxCatalog = currentOid > oidMaxCatalog ? currentOid : oidMaxCatalog;
+
+ resetStringInfo(sqlstrCatalog);
+ }
+ else
+ /* use SPI for user tables*/
{
- appendStringInfo(&sqlstr, " UNION ALL ");
+ userTablesNum++;
+ {
+ if (userTablesNum > 1)
+ {
+ appendStringInfo(sqlstrUser, " UNION ALL ");
+ }
+ appendStringInfo(sqlstrUser, "SELECT MAX(oid) AS oid FROM %s", classForm->relname.data);
+ }
}
- appendStringInfo(&sqlstr, "SELECT max(oid) AS oid FROM %s", tableNames[i]);
+
+ outerTuple = caql_getnext(pcqOuterCtx);
}
- appendStringInfo(&sqlstr, ") AS x");
- ret = SPI_execute(sqlstr.data, true, 1);
+ caql_endscan(pcqOuterCtx);
- if (ret > 0 && NULL != SPI_tuptable)
- {
- TupleDesc tupdesc = SPI_tuptable->tupdesc;
- SPITupleTable *tuptable = SPI_tuptable;
- HeapTuple tuple = tuptable->vals[0];
- char *oidString = SPI_getvalue(tuple, tupdesc, 1);
- if (NULL != oidString)
+ if (userTablesNum) {
+
+ appendStringInfo(sqlstrUser, ") AS x");
+
+ if (SPI_OK_CONNECT != SPI_connect())
{
- oidMax = DatumGetObjectId(DirectFunctionCall1(oidin, CStringGetDatum(oidString)));
+ ereport(ERROR, (errcode(ERRCODE_CDB_INTERNAL_ERROR),
+ errmsg("Unable to connect to execute internal query for HCatalog.")));
}
- }
- pfree(sqlstr.data);
+ ret = SPI_execute(sqlstrUser->data, true, 1);
+ if (ret > 0 && NULL != SPI_tuptable) {
+ TupleDesc tupdesc = SPI_tuptable->tupdesc;
+ SPITupleTable *tuptable = SPI_tuptable;
+ HeapTuple tuple = tuptable->vals[0];
+ char *oidString = SPI_getvalue(tuple, tupdesc, 1);
+ if (NULL != oidString)
+ {
+ oidMaxUser = DatumGetObjectId(DirectFunctionCall1(oidin, CStringGetDatum(oidString)));
+ }
+ }
+ }
+
+ pfree(sqlstrCatalog->data);
+ pfree(sqlstrUser->data);
SPI_finish();
+ elog(DEBUG1, "Highest Oid currently in use among catalog tables: %u", oidMaxCatalog);
+ elog(DEBUG1, "Highest Oid currently in use among user tables having oid: %u", oidMaxUser);
+
+ oidMax = oidMaxCatalog > oidMaxUser ? oidMaxCatalog : oidMaxUser;
+
elog(DEBUG1, "Highest Oid currently in use: %u", oidMax);
return oidMax;