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 ; }
Turn sequential scan to index scan for group by if possible