public IDataStructure GetOutputStructure(IExpression expression)
        {
            if (expression.IsApplyComponent)
            {
                return(this._joinApplyMeasuresOp.GetMeasuresStructure(expression));
            }

            IDataStructure ds1 = expression.OperandsCollection.ToArray()[0].Structure;
            IDataStructure ds2 = expression.OperandsCollection.ToArray()[1].Structure;

            if (!ds1.IsNumericStructure(true) || !ds2.IsNumericStructure(true))
            {
                throw new VtlOperatorError(expression, this.Name, "Expected numeric components.");
            }

            if (!ds1.IsSingleComponent && ds2.IsSingleComponent)
            {
                return(NumericStructure.GetDatasetScalarMixedStructure(ds1, ds2));
            }
            else if (ds1.IsSingleComponent && !ds2.IsSingleComponent)
            {
                return(NumericStructure.GetDatasetScalarMixedStructure(ds2, ds1));
            }
            else if (!ds1.IsSingleComponent && !ds2.IsSingleComponent)
            {
                IDataStructure structure;

                if (ds1.IsSupersetOf(ds2, true, false, true))
                {
                    structure = NumericStructure.GetDatasetsMixedStructure(ds1.WithAttributesOf(ds2), ds2);
                }
                else if (ds2.IsSupersetOf(ds1, true, false, true))
                {
                    structure = NumericStructure.GetDatasetsMixedStructure(ds2.WithAttributesOf(ds1), ds1);
                }
                else
                {
                    throw new VtlOperatorError(expression, this.Name, "Structures of datasets don't match.");
                }

                return(structure);
            }

            if (!ds1.Components[0].ValueDomain.DataType.In(BasicDataType.Integer, BasicDataType.Number, BasicDataType.None) ||
                !ds2.Components[0].ValueDomain.DataType.In(BasicDataType.Integer, BasicDataType.Number, BasicDataType.None))
            {
                throw new VtlOperatorError(expression, this.Name, "Expected numeric scalar values.");
            }

            if (ds2.Components[0].ValueDomain.DataType == BasicDataType.Number)
            {
                return(ds2.GetCopy());
            }
            return(ds1.GetCopy());
        }
        public IDataStructure GetOutputStructure(IExpression expression)
        {
            if (expression.IsApplyComponent)
            {
                return(this._joinApplyMeasuresOp.GetMeasuresStructure(expression));
            }

            IExpression expr1 = expression.OperandsCollection.ToArray()[0];
            IExpression expr2 =
                expression.OperandsCollection.ToArray().Length > 1 ?
                expression.OperandsCollection.ToArray()[1] :
                null;

            if (!expr1.Structure.IsNumericStructure(true))
            {
                throw new VtlOperatorError(expression, this.Name, "Expected numeric components.");
            }

            IDataStructure ds1 = expr1.Structure.GetCopy();

            if (expr2 != null)
            {
                IDataStructure ds2 = expr2.Structure.GetCopy();

                if (expr2.ExpressionText != "_")
                {
                    if (this.Symbol.In("power", "log", "round", "trunc") && !ds2.IsSingleComponent)
                    {
                        throw new VtlOperatorError(expression, this.Name, "Expected single component.");
                    }
                    if (this.Symbol.In("log", "round", "trunc") && (!ds2.IsSingleComponent || !ds2.Components.First().ValueDomain.DataType.In(BasicDataType.Integer, BasicDataType.None)))
                    {
                        throw new VtlOperatorError(expression, this.Name, "Type of component must be integer.");
                    }
                    if (this.Symbol.In("mod", "power") && !ds2.IsNumericStructure(true))
                    {
                        throw new VtlOperatorError(expression, this.Name, "Expected numeric components.");
                    }
                }

                if (!ds2.IsSingleComponent)
                {
                    if (ds1.IsSupersetOf(ds2, true, false, true))
                    {
                        ds1 = NumericStructure.GetDatasetsMixedStructure(ds1.WithAttributesOf(ds2), ds2);
                    }
                    else if (ds2.IsSupersetOf(ds1, true, false, true))
                    {
                        ds1 = NumericStructure.GetDatasetsMixedStructure(ds2.WithAttributesOf(ds1), ds1);
                    }
                    else if (ds1.IsSingleComponent)
                    {
                        ds1 = NumericStructure.GetDatasetScalarMixedStructure(ds2.WithAttributesOf(ds1), ds1);
                    }
                    else
                    {
                        throw new VtlOperatorError(expression, this.Name, "Structures of datasets don't match.");
                    }
                }
            }

            if (ds1.IsSingleComponent)
            {
                if (this.Symbol.In("ceil", "floor"))
                {
                    return(this._dsResolver("int_var", ComponentType.Measure, BasicDataType.Integer));
                }
                return(this._dsResolver("num_var", ComponentType.Measure, BasicDataType.Number));
            }
            else
            {
                List <StructureComponent> components = ds1.Measures.ToList();
                for (int i = 0; i < components.Count; i++)
                {
                    if (this.Symbol.In("ceil", "floor"))
                    {
                        components[i].ValueDomain = new ValueDomain(BasicDataType.Integer);
                    }
                    else
                    {
                        components[i].ValueDomain = new ValueDomain(BasicDataType.Number);
                    }
                }
            }

            return(ds1);
        }