public function assembleColumnName($tableAlias) {
        $callback = new ColumnStatementCompositeEntityParser__TableAliasUpdater(NULL, $tableAlias, TRUE);

        $parser = new FormulaExpressionParser(SQLFormulaExpressionHandler::LANGUAGE__SQL);
        return $parser->parse($this->function, array($callback, 'updateTableAlias'));
    }
    protected function generateFunction($columnPrefix, ColumnMetaData $parentColumn, $configuration, $allowDate, $allowTime) {
        if (($configuration['part'] == 'date') && !$allowDate) {
            return;
        }
        if (($configuration['part'] == 'date:fiscal') && (!$allowDate || (FiscalYearConfiguration::$FIRST_MONTH == 1))) {
            return;
        }
        if (($configuration['part'] == 'time') && !$allowTime) {
            return;
        }

        // preparing extension for date value formatting
        $key = $this->datasourceHandler->getDataSourceType();
        if (!isset($this->dateFormatExtensions[$key])) {
            $this->dateFormatExtensions[$key] = $this->datasourceHandler->getExtension('formatDateValue');
        }
        $dateFormatExtension = $this->dateFormatExtensions[$key];

        // preparing expression for calculated column
        $extensionMethodName = $configuration['methodName'];
        try {
            $expression = $dateFormatExtension->$extensionMethodName($this->datasourceHandler);
        }
        catch (UnsupportedOperationException $e) {
            $expression = FALSE;
        }

        if ($expression === FALSE) {
            $column = new ColumnMetaData();
            $column->used = FALSE;
        }
        else {
            $formulaExpressionParser = new FormulaExpressionParser(SQLFormulaExpressionHandler::LANGUAGE__SQL);

            $column = new FormulaMetaData();
            $column->type->applicationType = $configuration['datatype'];
            $column->source = str_replace(
                array('<columnName>', '<fiscalYearOffset>'),
                array(
                    $formulaExpressionParser->assemble($columnPrefix),
                    (12 - FiscalYearConfiguration::$FIRST_MONTH + 1)),
                $expression);
        }
        $column->name = $columnPrefix . '__' . $configuration['name'];
        $column->publicName = t($configuration['publicName']);
        $column->loaderName = get_class($this);

        // processing nested elements
        if (isset($configuration['elements'])) {
            foreach ($configuration['elements'] as $nestedConfiguration) {
                $this->generateFunction($columnPrefix, $column, $nestedConfiguration, $allowDate, $allowTime);
            }
        }

        if (($expression !== FALSE) || (count($column->branches) != 0)) {
            $parentColumn->branches[] = $column;
        }
    }
    public static function cleanFunctionParameters($datasetName, $columns, $parameters, $orderBy, array $options = NULL) {
        $metamodel = data_controller_get_metamodel();
        $dataset = $metamodel->getDataset($datasetName);

        $cleanedColumns = ArrayHelper::trim($columns);

        $cleanedParameters = NULL;
        if (isset($parameters)) {
            foreach ($parameters as $key => $value) {
                $key = StringHelper::trim($key);

                // ignoring system parameters
                list($elementNameSpace) = AbstractDatasetUIMetaDataGenerator::splitElementUIMetaDataName($key);
                if (!isset($elementNameSpace)) {
                    continue;
                }

                $cleanedParameters[$key] = $value;
            }
        }

        $cleanedOrderBy = NULL;
        ArrayHelper::addUniqueValues($cleanedOrderBy, ArrayHelper::trim($orderBy));

        $cleanedOptions = NULL;
        if (isset($options)) {
            foreach ($options as $name => $option) {
                $cleanedOption = NULL;
                if (isset($option)) {
                    if ($name == AbstractQueryRequest::OPTION__FORMULA_DEF) {
                        // cleaning all formulas
                        foreach ($option as $index => $formula) {
                            $cleanedFormula = clone $formula;

                            $parser = new FormulaExpressionParser($cleanedFormula->expressionLanguage);
                            $cleanedFormula->source = $parser->parse($cleanedFormula->source, 'DatasetUIMetaDataQueryHelper::cleanFormulaExpressionColumnNames');

                            $cleanedOption[$index] = $cleanedFormula;
                        }

                        // assembling clean formulas to calculate 'measure' flag
                        if (isset($cleanedOption)) {
                            $columnReferenceFactory = new CompositeColumnReferenceFactory(array(
                                $dataset,
                                new FormulaReferenceFactory($cleanedOption)));

                            $expressionAssembler = new FormulaExpressionAssembler($columnReferenceFactory);
                            foreach ($cleanedOption as $index => $cleanedFormula) {
                                // assembling full expressions to detect if any aggregation function present
                                $expression = $expressionAssembler->assemble($cleanedFormula);
                                // process the formula expression
                                $handler = FormulaExpressionLanguageFactory::getInstance()->getHandler($cleanedFormula->expressionLanguage);
                                $lexemes = $handler->lex($expression);
                                $syntaxTree = $handler->parse($lexemes);
                                // checking if the formula expression contains references to any aggregation functions
                                $cleanedFormula->isMeasure = $handler->isMeasure($syntaxTree);
                            }
                        }
                    }
                    elseif (is_array($option)) {
                        $cleanedOption = ArrayHelper::copy($option);
                    }
                    elseif (is_object($option)) {
                        $cleanedOption = clone $option;
                    }
                    else {
                        $cleanedOption = $option;
                    }
                }

                if (isset($cleanedOption)) {
                    $cleanedOptions[$name] = $cleanedOption;
                }
            }
        }

        // adjusting list of columns we need to return
        $requestedColumnNames = NULL;
        // preparing list of unique column names
        ArrayHelper::addUniqueValues($requestedColumnNames, $cleanedColumns);
        // adding columns which are used to sort result
        if ($cleanedOrderBy) {
            foreach ($cleanedOrderBy as $directionalColumnName) {
                list($columnName, $isSortAscending) = ColumnBasedComparator_AbstractSortingConfiguration::parseDirectionalColumnName($directionalColumnName);
                ArrayHelper::addUniqueValue($requestedColumnNames, $columnName);
            }
        }

        return array($requestedColumnNames, $cleanedParameters, $cleanedOrderBy, $cleanedOptions);
    }
    public function replaceColumnNames(ParserCallback $callback, &$callerSession) {
        $columnName = $callback->marker;

        $column = $this->columnReferenceFactory->getColumn($columnName);
        $this->approveColumn4ParticipationInExpression($column);

        if ($column->persistence == FormulaMetaData::PERSISTENCE__CALCULATED) {
            // checking if the column is already in the stack
            if (in_array($column->name, $this->columnAssemblingStack)) {
                $columnPublicNames = NULL;
                // adding columns from stack
                foreach ($this->columnAssemblingStack as $stackColumnName) {
                    $stackColumn = $this->dataset->getColumn($stackColumnName);
                    $columnPublicNames[] = $stackColumn->publicName;
                }
                // adding current processed column
                $columnPublicNames[] = $column->publicName;

                throw new IllegalStateException(t(
                    'Circular reference in formula expression is not allowed: %stack',
                    array('%stack' => ArrayHelper::serialize($columnPublicNames, ', ', TRUE, FALSE))));
            }

            array_push($this->columnAssemblingStack, $column->name);

            $language = isset($column->expressionLanguage) ? $column->expressionLanguage : NULL;
            $parser = new FormulaExpressionParser($language);

            $expression = $parser->expressionLanguageHandler->clean($column->source);

            $callback->marker = $parser->parse($expression, array($this, 'replaceColumnNames'));

            array_pop($this->columnAssemblingStack);

            $callback->removeDelimiters = TRUE;
        }
    }
    public function assemble(Statement $statement, $useTableNameAsAlias) {
        $callback = new ColumnStatementCompositeEntityParser__ColumnNameAdjuster(TRUE);

        $parser = new FormulaExpressionParser(SQLFormulaExpressionHandler::LANGUAGE__SQL);
        return $parser->parse($this->value, array($callback, 'adjustCallbackObject'));
    }
 protected static function registerFactMeasure(CubeMetaData $cube, ColumnMetaData $column, $functionName, $additivity, $selectedApplicationType = NULL)
 {
     $measureName = StarSchemaNamingConvention::getFactRelatedMeasureName($column->name, $functionName);
     $measure = $cube->registerMeasure($measureName);
     $measure->publicName = t($functionName);
     $measure->description = t("System generated '@functionName' measure for '@columnName' column", array('@functionName' => $measure->publicName, '@columnName' => $column->publicName));
     $measure->used = FALSE;
     $expression = FALSE;
     if ($column->persistence == FormulaMetaData::PERSISTENCE__CALCULATED) {
         if ($column->isUsed()) {
             try {
                 $expressionAssembler = new FormulaExpressionAssembler($cube->factsDataset);
                 $expression = $expressionAssembler->assemble($column);
                 $measure->used = TRUE;
             } catch (Exception $e) {
                 $message = t("@functionName measure assembled with errors. @error", array('@functionName' => $functionName, '@error' => $e->getMessage()));
                 $measure->functionError = $message;
                 LogHelper::log_warn($message);
             }
         } else {
             $measure->functionError = t("@functionName measure was not assembled for the unused column", array('@functionName' => $functionName));
         }
     } else {
         $formulaExpressionParser = new FormulaExpressionParser(SQLFormulaExpressionHandler::LANGUAGE__SQL);
         $expression = $formulaExpressionParser->assemble($column->name);
         $measure->used = TRUE;
     }
     $measure->function = $expression === FALSE ? FALSE : $functionName . '(' . $expression . ')';
     $measure->additivity = $additivity;
     $measure->type->applicationType = isset($selectedApplicationType) ? $selectedApplicationType : $column->type->applicationType;
     $measure->type->scale = $column->type->scale;
 }