private Column undeclaredHKeyColumn(HKeyColumn hKeyColumn) { Column undeclaredHKeyColumn = null; int rootMostDepth = rootMostTable().getDepth(); List<Column> equivalentColumns = hKeyColumn.equivalentColumns(); switch (getJoinType()) { case LEFT: // use a rootward bias, but no more rootward than the rootmost table for (Column equivalentColumn : equivalentColumns) { int equivalentColumnDepth = equivalentColumn.getTable().getDepth(); if (undeclaredHKeyColumn == null && equivalentColumnDepth >= rootMostDepth) { undeclaredHKeyColumn = equivalentColumn; } } break; case RIGHT: // use a leafward bias, but no more leafward than the leafdmost table int leafMostDepth = leafMostTable().getDepth(); for (ListIterator<Column> reverseCols = equivalentColumns.listIterator(equivalentColumns.size()); reverseCols.hasPrevious(); ) { Column equivalentColumn = reverseCols.previous(); int equivalentColumnDepth = equivalentColumn.getTable().getDepth(); if (undeclaredHKeyColumn == null && equivalentColumnDepth <= leafMostDepth) { undeclaredHKeyColumn = equivalentColumn; } } break; } if (undeclaredHKeyColumn == null) { undeclaredHKeyColumn = hKeyColumn.column(); } return undeclaredHKeyColumn; }
private int substituteHKeyColumnPosition(HKeyColumn hKeyColumn) { int substituteHKeyColumnPosition = -1; // Given an hkey row, we need to construct an hkey for some table, either a table covered by the // index // or some ancestor table. hKeyColumn is an hkey column of that table. If we're here, then // hKeyColumn.column() cannot be obtained from the index row itself, so the question is: which // of the // hKeyColumn's equivalent columns should be used. // - If the hkey column is above the root: Use the rootmost equivalent column of the hkey // columns in the index // row. // - Otherwise the hkey column belongs to a table covered by the index. // - For a left join index, use the nearest rootward equivalent column. // - For a right join index, use the nearest leafward equivalent column. List<Column> equivalentColumns = hKeyColumn.equivalentColumns(); // sorted by depth, root first Integer targetTableDepth = hKeyColumn.column().getTable().getDepth(); if (targetTableDepth < rootMostTable().getDepth()) { for (int i = 0; substituteHKeyColumnPosition == -1 && i < equivalentColumns.size(); i++) { Column equivalentColumn = equivalentColumns.get(i); substituteHKeyColumnPosition = positionOf(equivalentColumn); } } else { switch (getJoinType()) { case LEFT: for (int i = 0; i < equivalentColumns.size(); i++) { Column equivalentColumn = equivalentColumns.get(i); int equivalentColumnPosition = positionOf(equivalentColumn); if (equivalentColumnPosition != -1 && depth(equivalentColumn) < targetTableDepth) { substituteHKeyColumnPosition = equivalentColumnPosition; } } break; case RIGHT: for (int i = equivalentColumns.size() - 1; i >= 0; i--) { Column equivalentColumn = equivalentColumns.get(i); int equivalentColumnPosition = positionOf(equivalentColumn); if (equivalentColumnPosition != -1 && depth(equivalentColumn) > targetTableDepth) { substituteHKeyColumnPosition = equivalentColumnPosition; } } break; } } assert substituteHKeyColumnPosition != -1 : hKeyColumn; return substituteHKeyColumnPosition; }
private void computeHKeyDerivations(Map<Table, Integer> ordinalMap) { indexToHKeys = new IndexToHKey[leafMostTable().getDepth() + 1]; Table table = leafMostTable(); while (table != null) { int tableDepth = table.getDepth(); assert tableDepth <= leafMostTable().getDepth() : table; AssociationBuilder hKeyBuilder = new AssociationBuilder(); HKey hKey = table.hKey(); for (HKeySegment hKeySegment : hKey.segments()) { hKeyBuilder.toHKeyEntry(ordinalMap.get(hKeySegment.table()), -1); for (HKeyColumn hKeyColumn : hKeySegment.columns()) { int indexColumnPosition = positionOf(hKeyColumn.column()); if (indexColumnPosition == -1) { indexColumnPosition = substituteHKeyColumnPosition(hKeyColumn); } hKeyBuilder.toHKeyEntry(-1, indexColumnPosition); } } indexToHKeys[tableDepth] = hKeyBuilder.createIndexToHKey(); table = table.getParentTable(); } }