public static function selectReferencedColumnNames4ReferenceLink(array $linkExecutionStack, array $columnNames = NULL) { if (!isset($columnNames)) { return NULL; } $selectedColumnNames = NULL; $linkExecutionStackSize = count($linkExecutionStack); foreach ($columnNames as $columnName) { $columnNameReferences = ReferencePathHelper::splitReferencePath($columnName); $referenceSegmentCount = count($columnNameReferences); for ($referenceSegmentIndex = $referenceSegmentCount - 1, $stackPreviousIndex = -1; $referenceSegmentIndex >= 0; $referenceSegmentIndex--) { $reference = $columnNameReferences[$referenceSegmentIndex]; list($referencedDatasetName, $referencedColumnName) = ReferencePathHelper::splitReference($reference); if (isset($referencedDatasetName)) { // looking for related link in stack $foundInStack = FALSE; for ($stackIndex = $stackPreviousIndex + 1; $stackIndex < $linkExecutionStackSize && !$foundInStack; $stackIndex++) { $stackLink = $linkExecutionStack[$stackIndex]; if ($referencedDatasetName != $stackLink->dataset->name) { continue; } // checking parent column name if ($stackIndex < $linkExecutionStackSize - 1 && $referenceSegmentIndex > 0) { $nextStackLine = $linkExecutionStack[$stackIndex + 1]; // checking number of columns. It has to be single column if (count($nextStackLine->parentColumnNames) > 1) { break; } // checking if the parent column matches if (array_search($referencedColumnName, $nextStackLine->parentColumnNames) === FALSE) { break; } } $stackPreviousIndex = $stackIndex; $foundInStack = TRUE; } if (!$foundInStack) { break; } // we did not reach end of the execution stack if ($stackPreviousIndex < $linkExecutionStackSize - 1) { continue; } } else { if ($linkExecutionStackSize > 1) { // this column belongs to root link but we are working with nested link break; } } // original column name would be only the portion of the reference path $adjustedColumnName = ReferencePathHelper::assembleReferencePath(array_slice($columnNameReferences, $referenceSegmentIndex)); $selectedColumnNames[$adjustedColumnName] = $referencedColumnName; break; } } return $selectedColumnNames; }
protected function findColumnTableByReferencePath($referencePath) { $tableCount = count($this->tables); $references = ReferencePathHelper::splitReferencePath($referencePath); $references = array_reverse($references); $tableIndex = NULL; for ($i = 0, $refcount = count($references); $i < $refcount - 1; $i++) { $reference = $references[$i]; list($referencedDatasetName, $referencedColumnName) = ReferencePathHelper::splitReference($reference); if (!isset($referencedDatasetName)) { continue; } $nextReference = $references[$i + 1]; list($nextReferencedDatasetName, $nextReferencedColumnName) = ReferencePathHelper::splitReference($nextReference); if (!isset($nextReferencedDatasetName)) { continue; } $branchIndex = NULL; for ($j = (isset($tableIndex) ? $tableIndex : 0); $j < $tableCount; $j++) { $table = $this->tables[$j]; if ($table->dataset->name == $referencedDatasetName) { for ($k = $j + 1; $k < $tableCount; $k++) { $nextTable = $this->tables[$k]; if (($nextTable->dataset->name == $nextReferencedDatasetName) && ($nextTable->conditions[0]->joinValue->tableAlias == $table->alias) && ($nextTable->conditions[0]->joinValue->columnName == $referencedColumnName)) { $branchIndex = $k; break 2; } } } } if (!isset($branchIndex)) { return NULL; } $tableIndex = $branchIndex; } return isset($tableIndex) ? $this->tables[$tableIndex] : NULL; }
public function prepareStatementGenerationContext(AbstractCubeQueryRequest $request, CubeMetaData $cube) { $metamodel = data_controller_get_metamodel(); $generationContext = new __DefaultQueryEngine_StatementGenerationContext(); // checking if we use any non-additive measures in this request $foundNonAdditiveMeasure = FALSE; foreach ($cube->measures as $measure) { $measureName = $measure->name; $additivity = $measure->getAdditivity(); if (($additivity == MeasureAdditivity::ADDITIVE) || ($additivity == MeasureAdditivity::SEMI_ADDITIVE)) { continue; } $selectedMeasure = $request->findMeasure($measureName); $queriedMeasure = $request->findMeasureQuery($measureName); if (!isset($selectedMeasure) && !isset($queriedMeasure)) { continue; } $foundNonAdditiveMeasure = TRUE; break; } // checking if only columns with non-unique values were requested for some dimensions if (isset($cube->dimensions)) { foreach ($cube->dimensions as $dimension) { $dimensionName = $dimension->name; $selectedDimension = $request->findDimension($dimensionName); $queriedDimension = $request->findDimensionQuery($dimensionName); if (!isset($selectedDimension) && !isset($queriedDimension)) { continue; } // checking if at least one returned column is unique $selectedUniqueColumn = NULL; if (isset($selectedDimension)) { $selectedColumnNames = $selectedDimension->getColumnNames(); if (isset($selectedColumnNames)) { // 02/26/2014 it is possible to have columns but not lookup dataset. the case is when we connect with extension table (PK-to-PK connection) if (isset($dimension->datasetName)) { $selectedUniqueColumn = FALSE; } else { // 07/30/2014 it could be just a column expression ($column->branches) foreach ($selectedColumnNames as $selectedColumnName) { // TODO do not try to optimize query generation for 'complex' references $references = ReferencePathHelper::splitReferencePath($selectedColumnName); if (count($references) > 1) { $selectedUniqueColumn = FALSE; break; } } } } } $queriedByColumns = FALSE; if (isset($queriedDimension)) { $queriedColumnNames = $queriedDimension->getColumnNames(); if (isset($queriedColumnNames)) { if (isset($dimension->datasetName)) { $queriedByColumns = TRUE; } } } $joinWithLookup = FALSE; if (!isset($selectedUniqueColumn) && !$queriedByColumns) { // there is not need to join with lookup. We do not work with any columns $joinWithLookup = NULL; } elseif ($foundNonAdditiveMeasure) { $joinWithLookup = TRUE; } elseif ($queriedByColumns) { $joinWithLookup = TRUE; } elseif ($selectedUniqueColumn === FALSE) { $joinWithLookup = TRUE; } // FIXME to temporary resolve an issue when joining datasets. We need to change a way SQL engine works if (isset($request->referencedRequests) || $request->referenced) { $joinWithLookup = TRUE; } $generationContext->dimensionJoinPhase[__DefaultQueryEngine_StatementGenerationContext::DIMENSION_JOIN_PHASE__GROUPING_INITIAL][$dimensionName] = isset($joinWithLookup) ? $joinWithLookup : FALSE; $generationContext->dimensionJoinPhase[__DefaultQueryEngine_StatementGenerationContext::DIMENSION_JOIN_PHASE__GROUPING_WITH_LOOKUP_AFTER][$dimensionName] = isset($joinWithLookup) ? !$joinWithLookup : FALSE; } } return $generationContext; }