docs: private AbstractPlanNode indexAccessForGroupByExprs(SeqScanPlanNode root,
              IndexGroupByInfo gbInfo) {
          if (! root.isPersistentTableScan()) {
              // subquery and common tables are not handled
              return root;
          }
  
          String fromTableAlias = root.getTargetTableAlias();
          assert(fromTableAlias != null);
  
          List<ParsedColInfo> groupBys = m_parsedSelect.groupByColumns();
          Table targetTable = m_catalogDb.getTables().get(root.getTargetTableName());
          assert(targetTable != null);
          CatalogMap<Index> allIndexes = targetTable.getIndexes();
  
          List<Integer> maxCoveredGroupByColumns = new ArrayList<>();
          ArrayList<AbstractExpression> maxCoveredBindings = null;
          Index pickedUpIndex = null;
          boolean foundAllGroupByCoveredIndex = false;
  
          for (Index index : allIndexes) {
              if ( ! IndexType.isScannable(index.getType())) {
                  continue;
              }
  
              if ( ! index.getPredicatejson().isEmpty()) {
                  // do not try to look at Partial/Sparse index
                  continue;
              }
  
              ArrayList<AbstractExpression> bindings = new ArrayList<>();
              List<Integer> coveredGroupByColumns = calculateGroupbyColumnsCovered(
                      index, fromTableAlias, bindings);
  
              if (coveredGroupByColumns.size() > maxCoveredGroupByColumns.size()) {
                  maxCoveredGroupByColumns = coveredGroupByColumns;
                  pickedUpIndex = index;
                  maxCoveredBindings = bindings;
  
                  if (maxCoveredGroupByColumns.size() == groupBys.size()) {
                      foundAllGroupByCoveredIndex = true;
                      break;
                  }
              }
          }
          if (pickedUpIndex == null) {
              return root;
          }
  
          IndexScanPlanNode indexScanNode = new IndexScanPlanNode(
                  root, null, pickedUpIndex, SortDirectionType.INVALID);
          indexScanNode.setForGroupingOnly();
          indexScanNode.setBindings(maxCoveredBindings);
  
          gbInfo.m_coveredGroupByColumns = maxCoveredGroupByColumns;
          gbInfo.m_canBeFullySerialized = foundAllGroupByCoveredIndex;
          return indexScanNode;
      }