diff --git a/src/backend/columnar/columnar_reader.c b/src/backend/columnar/columnar_reader.c index 5437a7c38..4cfb213e8 100644 --- a/src/backend/columnar/columnar_reader.c +++ b/src/backend/columnar/columnar_reader.c @@ -70,9 +70,8 @@ struct ColumnarReadState StripeReadState *stripeReadState; /* - * List of Var pointers for columns in the query. We use this both for - * getting vector of projected columns, and also when we want to build - * base constraint to find selected row chunks. + * Integer list of attribute numbers (1-indexed) for columns needed by the + * query. */ List *projectedColumnList; @@ -139,6 +138,8 @@ static Datum ColumnDefaultValue(TupleConstr *tupleConstraints, /* * ColumnarBeginRead initializes a columnar read operation. This function returns a * read handle that's used during reading rows and finishing the read operation. + * + * projectedColumnList is an integer list of attribute numbers (1-indexed). */ ColumnarReadState * ColumnarBeginRead(Relation relation, TupleDesc tupleDescriptor, @@ -415,12 +416,14 @@ ReadChunkGroupNextRow(ChunkGroupReadState *chunkGroupReadState, Datum *columnVal */ memset(columnNulls, true, sizeof(bool) * chunkGroupReadState->columnCount); - Var *projectedColumn = NULL; - foreach_ptr(projectedColumn, chunkGroupReadState->projectedColumnList) + int attno; + foreach_int(attno, chunkGroupReadState->projectedColumnList) { const ChunkData *chunkGroupData = chunkGroupReadState->chunkGroupData; const int rowIndex = chunkGroupReadState->currentRow; - uint32 columnIndex = projectedColumn->varattno - 1; + + /* attno is 1-indexed; existsArray is 0-indexed */ + const uint32 columnIndex = attno - 1; if (chunkGroupData->existsArray[columnIndex][rowIndex]) { @@ -1010,12 +1013,12 @@ static bool * ProjectedColumnMask(uint32 columnCount, List *projectedColumnList) { bool *projectedColumnMask = palloc0(columnCount * sizeof(bool)); - ListCell *columnCell = NULL; + int attno; - foreach(columnCell, projectedColumnList) + foreach_int(attno, projectedColumnList) { - Var *column = (Var *) lfirst(columnCell); - uint32 columnIndex = column->varattno - 1; + /* attno is 1-indexed; projectedColumnMask is 0-indexed */ + int columnIndex = attno - 1; projectedColumnMask[columnIndex] = true; } diff --git a/src/backend/columnar/columnar_tableam.c b/src/backend/columnar/columnar_tableam.c index c3ed1bb07..27e09d3c0 100644 --- a/src/backend/columnar/columnar_tableam.c +++ b/src/backend/columnar/columnar_tableam.c @@ -119,34 +119,6 @@ static Datum * detoast_values(TupleDesc tupleDesc, Datum *orig_values, bool *isn /* Custom tuple slot ops used for columnar. Initialized in columnar_tableam_init(). */ static TupleTableSlotOps TTSOpsColumnar; -static List * -RelationColumnList(TupleDesc tupdesc) -{ - List *columnList = NIL; - - for (int i = 0; i < tupdesc->natts; i++) - { - Index varno = 1; - AttrNumber varattno = i + 1; - Oid vartype = tupdesc->attrs[i].atttypid; - int32 vartypmod = tupdesc->attrs[i].atttypmod; - Oid varcollid = tupdesc->attrs[i].attcollation; - Index varlevelsup = 0; - - if (tupdesc->attrs[i].attisdropped) - { - continue; - } - - Var *var = makeVar(varno, varattno, vartype, vartypmod, - varcollid, varlevelsup); - columnList = lappend(columnList, var); - } - - return columnList; -} - - static const TupleTableSlotOps * columnar_slot_callbacks(Relation relation) { @@ -161,9 +133,9 @@ columnar_beginscan(Relation relation, Snapshot snapshot, uint32 flags) { int natts = relation->rd_att->natts; - Bitmapset *attr_needed = NULL; - attr_needed = bms_add_range(attr_needed, 0, natts - 1); + /* attr_needed represents 0-indexed attribute numbers */ + Bitmapset *attr_needed = bms_add_range(NULL, 0, natts - 1); /* the columnar access method does not use the flags, they are specific to heap */ flags = 0; @@ -241,18 +213,14 @@ static ColumnarReadState * init_columnar_read_state(Relation relation, TupleDesc tupdesc, Bitmapset *attr_needed, List *scanQual) { - List *columnList = RelationColumnList(tupdesc); - ListCell *columnCell = NULL; - List *neededColumnList = NIL; - /* only collect columns that we need for the scan */ - foreach(columnCell, columnList) + for (int i = 0; i < tupdesc->natts; i++) { - Var *var = castNode(Var, lfirst(columnCell)); - if (bms_is_member(var->varattno - 1, attr_needed)) + if (bms_is_member(i, attr_needed) && !tupdesc->attrs[i].attisdropped) { - neededColumnList = lappend(neededColumnList, var); + /* attr_needed is 0-indexed; neededColumnList is 1-indexed */ + neededColumnList = lappend_int(neededColumnList, i + 1); } } @@ -648,8 +616,18 @@ columnar_relation_copy_for_cluster(Relation OldHeap, Relation NewHeap, columnarOptions, targetDesc); + List *projectedColumnList = NIL; + for (int i = 0; i < sourceDesc->natts; i++) + { + if (!sourceDesc->attrs[i].attisdropped) + { + /* projectedColumnList is 1-indexed */ + projectedColumnList = lappend_int(projectedColumnList, i + 1); + } + } + ColumnarReadState *readState = ColumnarBeginRead(OldHeap, sourceDesc, - RelationColumnList(sourceDesc), + projectedColumnList, NULL); Datum *values = palloc0(sourceDesc->natts * sizeof(Datum));