/* * get_proposed_default_constraint * * This function returns the negation of new_part_constraints, which * would be an integral part of the default partition constraints after * addition of the partition to which the new_part_constraints belongs. */ List * get_proposed_default_constraint(List *new_part_constraints) { Expr *defPartConstraint; defPartConstraint = make_ands_explicit(new_part_constraints); /* * Derive the partition constraints of default partition by negating the * given partition constraints. The partition constraint never evaluates * to NULL, so negating it like this is safe. */ defPartConstraint = makeBoolExpr(NOT_EXPR, list_make1(defPartConstraint), -1); /* Simplify, to put the negated expression into canonical form */ defPartConstraint = (Expr *) eval_const_expressions(NULL, (Node *) defPartConstraint); defPartConstraint = canonicalize_qual(defPartConstraint, true); return make_ands_implicit(defPartConstraint); }
Datum gp_get_physical_index_relid(PG_FUNCTION_ARGS) { Oid rootOid = PG_GETARG_OID(0); Oid partOid = PG_GETARG_OID(1); LogicalIndexInfo logicalIndexInfo; Oid resultOid; int2vector *indexKeys; text *inText; Relation rel; logicalIndexInfo.nColumns = 0; logicalIndexInfo.indexKeys = NULL; logicalIndexInfo.indPred = NIL; logicalIndexInfo.indExprs = NIL; if (!PG_ARGISNULL(2)) { indexKeys = (int2vector *)PG_GETARG_POINTER(2); logicalIndexInfo.nColumns = indexKeys->dim1; logicalIndexInfo.indexKeys = (AttrNumber *)palloc0(indexKeys->dim1 * sizeof(AttrNumber)); for (int i = 0; i < indexKeys->dim1; i++) logicalIndexInfo.indexKeys[i] = indexKeys->values[i]; } if (!PG_ARGISNULL(3)) { Node *indPred; inText = PG_GETARG_TEXT_P(3); indPred = stringToNode(text_to_cstring(inText)); /* Perform the same normalization as relcache.c does. */ indPred = eval_const_expressions(NULL, indPred); indPred = (Node *) canonicalize_qual((Expr *) indPred); set_coercionform_dontcare(indPred); indPred = (Node *) make_ands_implicit((Expr *) indPred); fix_opfuncids(indPred); logicalIndexInfo.indPred = (List *) indPred; } if (!PG_ARGISNULL(4)) { Node *indExprs; inText = PG_GETARG_TEXT_P(4); indExprs = stringToNode(text_to_cstring(inText)); /* Perform the same normalization as relcache.c does. */ indExprs = eval_const_expressions(NULL, indExprs); set_coercionform_dontcare(indExprs); fix_opfuncids(indExprs); logicalIndexInfo.indExprs = (List *) indExprs; } logicalIndexInfo.indIsUnique = PG_GETARG_BOOL(5); AttrNumber *attMap = IndexScan_GetColumnMapping(rootOid, partOid); rel = heap_open(partOid, AccessShareLock); /* * The varno is hard-coded to 1 as the original getPhysicalIndexRelid was * using a hard-coded 1 for varattno mapping of logicalIndexInfo. */ IndexScan_MapLogicalIndexInfo(&logicalIndexInfo, attMap, 1); /* do the actual work */ resultOid = getPhysicalIndexRelid(rel, &logicalIndexInfo); if (attMap) { pfree(attMap); } heap_close(rel, AccessShareLock); return ObjectIdGetDatum(resultOid); }
/* * Parse AM-specific options, convert to text array form, validate. */ reloptions = transformRelOptions((Datum) 0, options, false, false); (void) index_reloptions(amoptions, reloptions, true); /* * Prepare arguments for index_create, primarily an IndexInfo structure. * Note that ii_Predicate must be in implicit-AND format. */ indexInfo = makeNode(IndexInfo); indexInfo->ii_NumIndexAttrs = numberOfAttributes; indexInfo->ii_Expressions = NIL; /* for now */ indexInfo->ii_ExpressionsState = NIL; indexInfo->ii_Predicate = make_ands_implicit(predicate); indexInfo->ii_PredicateState = NIL; indexInfo->ii_Unique = unique; indexInfo->ii_Concurrent = concurrent; classObjectId = (Oid *) palloc(numberOfAttributes * sizeof(Oid)); ComputeIndexAttrs(indexInfo, classObjectId, attributeList, relationId, accessMethodName, accessMethodId, isconstraint); heap_close(rel, NoLock); /* * Report index creation if appropriate (delay this till after most of the * error checks) */
void _bitmap_create_lov_heapandindex(Relation rel, Oid lovComptypeOid, Oid *lovHeapOid, Oid *lovIndexOid, Oid lovHeapRelfilenode, Oid lovIndexRelfilenode) { char lovHeapName[NAMEDATALEN]; char lovIndexName[NAMEDATALEN]; TupleDesc tupDesc; IndexInfo *indexInfo; ObjectAddress objAddr, referenced; Oid *classObjectId; int16 *coloptions; Oid heapid; Oid idxid; int indattrs; int i; Oid unusedArrayOid = InvalidOid; Assert(rel != NULL); /* create the new names for the new lov heap and index */ snprintf(lovHeapName, sizeof(lovHeapName), "pg_bm_%u", RelationGetRelid(rel)); snprintf(lovIndexName, sizeof(lovIndexName), "pg_bm_%u_index", RelationGetRelid(rel)); heapid = get_relname_relid(lovHeapName, PG_BITMAPINDEX_NAMESPACE); /* * If heapid exists, then this is happening during re-indexing. * We allocate new relfilenodes for lov heap and lov index. * * XXX Each segment db may have different relfilenodes for lov heap and * lov index, which should not be an issue now. Ideally, we would like each * segment db use the same oids. */ if (OidIsValid(heapid)) { Relation lovHeap; Relation lovIndex; Buffer btree_metabuf; Page btree_metapage; *lovHeapOid = heapid; idxid = get_relname_relid(lovIndexName, PG_BITMAPINDEX_NAMESPACE); Assert(OidIsValid(idxid)); *lovIndexOid = idxid; lovComptypeOid = get_rel_type_id(heapid); Assert(OidIsValid(lovComptypeOid)); lovHeap = heap_open(heapid, AccessExclusiveLock); lovIndex = index_open(idxid, AccessExclusiveLock); if (OidIsValid(lovHeapRelfilenode)) setNewRelfilenodeToOid(lovHeap, lovHeapRelfilenode); else setNewRelfilenode(lovHeap); if (OidIsValid(lovIndexRelfilenode)) setNewRelfilenodeToOid(lovIndex, lovIndexRelfilenode); else setNewRelfilenode(lovIndex); /* * After creating the new relfilenode for a btee index, this is not * a btree anymore. We create the new metapage for this btree. */ btree_metabuf = _bt_getbuf(lovIndex, P_NEW, BT_WRITE); Assert (BTREE_METAPAGE == BufferGetBlockNumber(btree_metabuf)); btree_metapage = BufferGetPage(btree_metabuf); _bt_initmetapage(btree_metapage, P_NONE, 0); /* XLOG the metapage */ if (!XLog_UnconvertedCanBypassWal() && !lovIndex->rd_istemp) { // Fetch gp_persistent_relation_node information that will be added to XLOG record. RelationFetchGpRelationNodeForXLog(lovIndex); _bt_lognewpage(lovIndex, btree_metapage, BufferGetBlockNumber(btree_metabuf)); } /* This cache value is not valid anymore. */ if (lovIndex->rd_amcache) { pfree(lovIndex->rd_amcache); lovIndex->rd_amcache = NULL; } MarkBufferDirty(btree_metabuf); _bt_relbuf(lovIndex, btree_metabuf); index_close(lovIndex, NoLock); heap_close(lovHeap, NoLock); return; } /* * create a new empty heap to store all attribute values with their * corresponding block number and offset in LOV. */ tupDesc = _bitmap_create_lov_heapTupleDesc(rel); Assert(rel->rd_rel != NULL); heapid = heap_create_with_catalog(lovHeapName, PG_BITMAPINDEX_NAMESPACE, rel->rd_rel->reltablespace, *lovHeapOid, rel->rd_rel->relowner, tupDesc, /* relam */ InvalidOid, RELKIND_RELATION, RELSTORAGE_HEAP, rel->rd_rel->relisshared, false, /* bufferPoolBulkLoad */ false, 0, ONCOMMIT_NOOP, NULL /* GP Policy */, (Datum)0, true, /* valid_opts */ true, &lovComptypeOid, &unusedArrayOid, /* persistentTid */ NULL, /* persistentSerialNum */ NULL); Assert(heapid == *lovHeapOid); /* * We must bump the command counter to make the newly-created relation * tuple visible for opening. */ CommandCounterIncrement(); objAddr.classId = RelationRelationId; objAddr.objectId = *lovHeapOid; objAddr.objectSubId = 0 ; referenced.classId = RelationRelationId; referenced.objectId = RelationGetRelid(rel); referenced.objectSubId = 0; recordDependencyOn(&objAddr, &referenced, DEPENDENCY_INTERNAL); /* * create a btree index on the newly-created heap. * The key includes all attributes to be indexed in this bitmap index. */ indattrs = tupDesc->natts - 2; indexInfo = makeNode(IndexInfo); indexInfo->ii_NumIndexAttrs = indattrs; indexInfo->ii_Expressions = NIL; indexInfo->ii_ExpressionsState = NIL; indexInfo->ii_Predicate = make_ands_implicit(NULL); indexInfo->ii_PredicateState = NIL; indexInfo->ii_Unique = true; indexInfo->opaque = NULL; classObjectId = (Oid *) palloc(indattrs * sizeof(Oid)); coloptions = (int16 *) palloc(indattrs * sizeof(int16)); for (i = 0; i < indattrs; i++) { Oid typid = tupDesc->attrs[i]->atttypid; indexInfo->ii_KeyAttrNumbers[i] = i + 1; classObjectId[i] = GetDefaultOpClass(typid, BTREE_AM_OID); coloptions[i] = 0; } idxid = index_create(*lovHeapOid, lovIndexName, *lovIndexOid, indexInfo, BTREE_AM_OID, rel->rd_rel->reltablespace, classObjectId, coloptions, 0, false, false, (Oid *) NULL, true, false, false, NULL); Assert(idxid == *lovIndexOid); }