static void gp_statistics_estimate_reltuples_relpages_ao_cs(Relation rel, float4 *reltuples, float4 *relpages) { AOCSFileSegInfo **aocsInfo = NULL; int nsegs = 0; double totalBytes = 0; AppendOnlyEntry *aoEntry; int64 hidden_tupcount; AppendOnlyVisimap visimap; /** * Ensure that the right kind of relation with the right type of storage is passed to us. */ Assert(rel->rd_rel->relkind == RELKIND_RELATION); Assert(RelationIsAoCols(rel)); *reltuples = 0.0; *relpages = 0.0; /* get table level statistics from the pg_aoseg table */ aoEntry = GetAppendOnlyEntry(RelationGetRelid(rel), SnapshotNow); aocsInfo = GetAllAOCSFileSegInfo(rel, aoEntry, SnapshotNow, &nsegs); if (aocsInfo) { int i = 0; int j = 0; for(i = 0; i < nsegs; i++) { for(j = 0; j < RelationGetNumberOfAttributes(rel); j++) { AOCSVPInfoEntry *e = getAOCSVPEntry(aocsInfo[i], j); Assert(e); totalBytes += e->eof_uncompressed; } /* Do not include tuples from an awaiting drop segment file */ if (aocsInfo[i]->state != AOSEG_STATE_AWAITING_DROP) { *reltuples += aocsInfo[i]->total_tupcount; } } /** * The planner doesn't understand AO's blocks, so need this method to try to fudge up a number for * the planner. */ *relpages = RelationGuessNumberOfBlocks(totalBytes); } AppendOnlyVisimap_Init(&visimap, aoEntry->visimaprelid, aoEntry->visimapidxid, AccessShareLock, SnapshotNow); hidden_tupcount = AppendOnlyVisimap_GetRelationHiddenTupleCount(&visimap); AppendOnlyVisimap_Finish(&visimap, AccessShareLock); (*reltuples) -= hidden_tupcount; pfree(aoEntry); return; }
/* * AOCSSegmentFileTruncateToEOF() * * Assumes that the segment file lock is already held. * * For the segment file is truncates to the eof. */ static void AOCSSegmentFileTruncateToEOF(Relation aorel, AOCSFileSegInfo *fsinfo) { const char *relname = RelationGetRelationName(aorel); int segno; int j; Assert(fsinfo); Assert(RelationIsAoCols(aorel)); segno = fsinfo->segno; relname = RelationGetRelationName(aorel); for (j = 0; j < fsinfo->vpinfo.nEntry; ++j) { int64 segeof; char filenamepath[MAXPGPATH]; AOCSVPInfoEntry *entry; File fd; int32 fileSegNo; entry = getAOCSVPEntry(fsinfo, j); segeof = entry->eof; /* Open and truncate the relation segfile to its eof */ MakeAOSegmentFileName(aorel, segno, j, &fileSegNo, filenamepath); elogif(Debug_appendonly_print_compaction, LOG, "Opening AO COL relation \"%s.%s\", relation id %u, relfilenode %u column #%d, logical segment #%d (physical segment file #%d, logical EOF " INT64_FORMAT ")", get_namespace_name(RelationGetNamespace(aorel)), relname, aorel->rd_id, aorel->rd_node.relNode, j, segno, fileSegNo, segeof); fd = OpenAOSegmentFile(aorel, filenamepath, fileSegNo, segeof); if (fd >= 0) { TruncateAOSegmentFile(fd, aorel, fileSegNo, segeof); CloseAOSegmentFile(fd); elogif(Debug_appendonly_print_compaction, LOG, "Successfully truncated AO COL relation \"%s.%s\", relation id %u, relfilenode %u column #%d, logical segment #%d (physical segment file #%d, logical EOF " INT64_FORMAT ")", get_namespace_name(RelationGetNamespace(aorel)), relname, aorel->rd_id, aorel->rd_node.relNode, j, segno, fileSegNo, segeof); } else { elogif(Debug_appendonly_print_compaction, LOG, "No gp_relation_node entry for AO COL relation \"%s.%s\", relation id %u, relfilenode %u column #%d, logical segment #%d (physical segment file #%d, logical EOF " INT64_FORMAT ")", get_namespace_name(RelationGetNamespace(aorel)), relname, aorel->rd_id, aorel->rd_node.relNode, j, segno, fileSegNo, segeof); } } }
static void DatabaseInfo_HandleAppendOnly( DatabaseInfo *info, HTAB *dbInfoRelHashTable, HTAB *relationIdHashTable, HTAB *pgAppendOnlyHashTable) { HASH_SEQ_STATUS iterateStatus; hash_seq_init(&iterateStatus, dbInfoRelHashTable); while (true) { DbInfoRel *dbInfoRel; dbInfoRel = (DbInfoRel*) hash_seq_search(&iterateStatus); if (dbInfoRel == NULL) break; if (dbInfoRel->relstorage == RELSTORAGE_AOROWS || dbInfoRel->relstorage == RELSTORAGE_AOCOLS) { AppendOnlyEntry *aoEntry; DbInfoRel *aosegDbInfoRel; int i; aoEntry = DatabaseInfo_FindPgAppendOnly( pgAppendOnlyHashTable, dbInfoRel->relationOid); if (Debug_persistent_print) elog(Persistent_DebugPrintLevel(), "DatabaseInfo_AddPgClassStoredRelation: Append-Only entry for relation id %u, relation name %s, " "blocksize %d, safefswritesize %d, compresslevel %d, major version %d, minor version %d, " " checksum %s, compresstype %s, columnstore %s, segrelid %u, segidxid %u, blkdirrelid %u, blkdiridxid %u, " " visimaprelid %u, visimapidxid %u", dbInfoRel->relationOid, dbInfoRel->relname, aoEntry->blocksize, aoEntry->safefswritesize, aoEntry->compresslevel, aoEntry->majorversion, aoEntry->minorversion, (aoEntry->checksum ? "true" : "false"), (aoEntry->compresstype ? aoEntry->compresstype : "NULL"), (aoEntry->columnstore ? "true" : "false"), aoEntry->segrelid, aoEntry->segidxid, aoEntry->blkdirrelid, aoEntry->blkdiridxid, aoEntry->visimaprelid, aoEntry->visimapidxid); /* * Translate the ao[cs]seg relation id to relfilenode. */ aosegDbInfoRel = DatabaseInfo_FindRelationId( relationIdHashTable, aoEntry->segrelid); Assert(aosegDbInfoRel != NULL); if (dbInfoRel->relstorage == RELSTORAGE_AOROWS) { FileSegInfo **aoSegfileArray; int totalAoSegFiles; Relation pg_aoseg_rel; pg_aoseg_rel = DirectOpen_PgAoSegOpenDynamic( aoEntry->segrelid, dbInfoRel->reltablespace, info->database, aosegDbInfoRel->relfilenodeOid); aoSegfileArray = GetAllFileSegInfo_pg_aoseg_rel( dbInfoRel->relname, aoEntry, pg_aoseg_rel, SnapshotNow, &totalAoSegFiles); for (i = 0; i < totalAoSegFiles; i++) { DatabaseInfo_AddAppendOnlyCatalogSegmentInfo( dbInfoRel, aoSegfileArray[i]->segno, aoSegfileArray[i]->eof); } DirectOpen_PgAoSegClose(pg_aoseg_rel); } else if (dbInfoRel->relstorage == RELSTORAGE_AOCOLS) { struct AOCSFileSegInfo **aocsSegfileArray; int totalAocsSegFiles; Relation pg_aocsseg_rel; pg_aocsseg_rel = DirectOpen_PgAoCsSegOpenDynamic( aoEntry->segrelid, dbInfoRel->reltablespace, info->database, aosegDbInfoRel->relfilenodeOid); aocsSegfileArray = GetAllAOCSFileSegInfo_pg_aocsseg_rel( dbInfoRel->relnatts, dbInfoRel->relname, aoEntry, pg_aocsseg_rel, SnapshotNow, &totalAocsSegFiles); for (i = 0; i < totalAocsSegFiles; i++) { int32 segmentFileNum; int columnNum; segmentFileNum = aocsSegfileArray[i]->segno; for (columnNum = 0; columnNum < dbInfoRel->relnatts; columnNum++) { AOCSVPInfoEntry *entry; entry = getAOCSVPEntry(aocsSegfileArray[i], columnNum); DatabaseInfo_AddAppendOnlyCatalogSegmentInfo( dbInfoRel, columnNum * AOTupleId_MultiplierSegmentFileNum + segmentFileNum, entry->eof); } } DirectOpen_PgAoCsSegClose(pg_aocsseg_rel); } } } }