/// <summary>
        /// Validates a persistent assignment expression.
        /// </summary>
        /// <param name="expr">The expression to validate.</param>
        private void ValidatePersistentAssignment(IExpression expr)
        {
            IDataStructure structure = null;

            try
            {
                structure = this._dataModel.GetDatasetStructure(expr.ResultName);

                string[] split = expr.ResultName.Split(@"\");
                if (split.Length == 1)
                {
                    expr.ResultName = $@"{this._dataModel.DefaultNamespace}\{expr.ResultName}";
                }
            }
            catch
            {
                if (structure == null)
                {
                    throw new InvalidOperationException($"'{expr.ResultName}' doesn't exist in the data model.");
                }
            }

            if (!structure.IsSupersetOf(expr.Structure, true, true))
            {
                throw new InvalidOperationException("Structures of datasets don't match.");
            }
        }
        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()[1];

            BasicDataType type1;
            BasicDataType type2;

            if (expr1.IsScalar)
            {
                type1 = expr1.Structure.Components[0].ValueDomain.DataType;
            }
            else
            {
                if (expr1.Structure.Measures.Count > 1)
                {
                    throw new VtlOperatorError(expression, this.Name, "Expected structure with only one measure.");
                }
                type1 = expr1.Structure.Measures[0].ValueDomain.DataType;
            }

            if (expr2.IsScalar)
            {
                type2 = expr2.Structure.Components[0].ValueDomain.DataType;
            }
            else
            {
                if (expr2.Structure.Measures.Count > 1)
                {
                    throw new VtlOperatorError(expression, this.Name, "Expected structure with only one measure.");
                }
                type2 = expr2.Structure.Measures[0].ValueDomain.DataType;
            }

            if (!type1.EqualsObj(type2) && !BasicDataType.None.In(type1, type2))
            {
                throw new VtlOperatorError(expression, this.Name, "Data types of parameters are not equal.");
            }

            IDataStructure structure;
            IDataStructure ds1 = expr1.Structure.GetCopy();
            IDataStructure ds2 = expr2.Structure.GetCopy();

            if (expr1.IsScalar && expr2.IsScalar)
            {
                return(this._dsResolver("bool_var", ComponentType.Measure, BasicDataType.Boolean));
            }
            if (!expr1.IsScalar && expr2.IsScalar)
            {
                structure = ds1.WithAttributesOf(ds2);
            }
            else if (expr1.IsScalar && !expr2.IsScalar)
            {
                structure = ds2.WithAttributesOf(ds1);
            }
            else
            {
                if (ds1.Measures[0].ComponentName != ds2.Measures[0].ComponentName)
                {
                    throw new VtlOperatorError(expression, this.Name, "Datasets doesn't fit.");
                }

                if (ds1.IsSupersetOf(ds2, true, false, true))
                {
                    structure = ds1.WithAttributesOf(ds2);
                }
                else if (ds2.IsSupersetOf(ds1, true, false, true))
                {
                    structure = ds2.WithAttributesOf(ds1);
                }
                else
                {
                    throw new VtlOperatorError(expression, this.Name, "Datasets doesn't fit.");
                }
            }

            structure.Measures.Clear();
            structure.Measures.Add(new StructureComponent(BasicDataType.Boolean, "bool_var"));
            structure.Measures[0].BaseComponentName = expr1.Structure.GetCopy().Measures[0].ComponentName;

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

            IDataStructure structure = null;
            IExpression    expr1     = expression.OperandsCollection.ToArray()[0];
            IExpression    expr2     =
                expression.OperandsCollection.ToArray().Length > 1 ?
                expression.OperandsCollection.ToArray()[1] :
                null;
            IExpression expr3 =
                expression.OperandsCollection.ToArray().Length > 2 ?
                expression.OperandsCollection.ToArray()[2] :
                null;
            IExpression expr4 =
                expression.OperandsCollection.ToArray().Length > 3 ?
                expression.OperandsCollection.ToArray()[3] :
                null;

            this.ValidateDataStructure(expression, expr1.Structure);

            if (expr2 != null && expr2.ExpressionText != "_")
            {
                if (this.Symbol.In("substr", "replace", "instr") && !(expr2.Structure.IsSingleComponent))
                {
                    throw new VtlOperatorError(expression, this.Name, $"Expected single component (arg2)");
                }
                if (this.Symbol.In("replace", "instr") && !expr2.Structure.Components.First().ValueDomain.DataType.In(BasicDataType.String, BasicDataType.None))
                {
                    throw new VtlOperatorError(expression, this.Name, $"Type of component must be string (arg2)");
                }
                if (this.Symbol.In("substr") && !expr2.Structure.Components.First().ValueDomain.DataType.In(BasicDataType.Integer, BasicDataType.None))
                {
                    throw new VtlOperatorError(expression, this.Name, $"Type of component must be integer (arg2)");
                }
                if (this.Symbol == "||")
                {
                    this.ValidateDataStructure(expression, expr2.Structure);
                    if (!expr2.IsScalar && expr1.IsScalar)
                    {
                        structure = expr2.Structure.GetCopy();
                    }
                    else if (!expr1.IsScalar && !expr2.IsScalar)
                    {
                        IDataStructure ds1 = expr1.Structure.GetCopy();
                        IDataStructure ds2 = expr2.Structure.GetCopy();

                        if (ds1.IsSupersetOf(ds2, true, false, true))
                        {
                            structure = ds1.WithAttributesOf(ds2);
                        }
                        else if (ds2.IsSupersetOf(ds1, true, false, true))
                        {
                            structure = ds2.WithAttributesOf(ds1);
                        }
                        else
                        {
                            throw new VtlOperatorError(expression, this.Name, "Structures of datasets don't match.");
                        }
                    }
                }
            }
            if (expr3 != null && expr3.ExpressionText != "_")
            {
                if (this.Symbol.In("substr", "replace", "instr") && !(expr3.Structure.IsSingleComponent))
                {
                    throw new VtlOperatorError(expression, this.Name, $"Expected single component (arg3)");
                }
                if (this.Symbol.In("substr", "instr") && !expr3.Structure.Components.First().ValueDomain.DataType.In(BasicDataType.Integer, BasicDataType.None))
                {
                    throw new VtlOperatorError(expression, this.Name, $"Type of component must be integer (arg3)");
                }
                if (this.Symbol.In("replace") && !expr3.Structure.Components.First().ValueDomain.DataType.In(BasicDataType.String, BasicDataType.None))
                {
                    throw new VtlOperatorError(expression, this.Name, $"Type of component must be string (arg3)");
                }
            }
            if (expr4 != null && expr4.ExpressionText != "_")
            {
                if (this.Symbol == "instr" && !(expr4.Structure.IsSingleComponent))
                {
                    throw new VtlOperatorError(expression, this.Name, $"Expected single component (arg4)");
                }
                if (this.Symbol == "instr" && !expr4.Structure.Components.First().ValueDomain.DataType.In(BasicDataType.Integer, BasicDataType.None))
                {
                    throw new VtlOperatorError(expression, this.Name, $"Type of component must be integer (arg4)");
                }
            }

            if (structure == null)
            {
                structure = expr1.Structure.GetCopy().WithAttributesOf(expr2?.Structure);
            }

            if (this.Symbol.In("instr", "length"))
            {
                if (expr1.Structure.Measures.Count > 1)
                {
                    throw new VtlOperatorError(expression, this.Name, "Expected structure with only one measure.");
                }
                structure.Measures.Clear();
                structure.Measures.Add(new StructureComponent(BasicDataType.Integer, "int_var"));
                structure.Measures[0].BaseComponentName = expr1.Structure.GetCopy().Measures[0].ComponentName;
            }
            else if (!structure.IsSingleComponent)
            {
                foreach (StructureComponent measure in structure.Measures)
                {
                    measure.ValueDomain = new ValueDomain(BasicDataType.String);
                }
            }
            else
            {
                return(this._dsResolver("string_var", ComponentType.Measure, BasicDataType.String));
            }

            return(structure);
        }
        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);
        }
        public IDataStructure GetOutputStructure(IExpression expression)
        {
            if (expression.IsApplyComponent)
            {
                return(this._joinApplyMeasuresOp.GetMeasuresStructure(expression));
            }

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

            if (!ds1.IsSingleComponent && ds1.Measures.Count > 1)
            {
                throw new VtlOperatorError(expression, this.Name, "Expected single measure structure.");
            }
            if (!ds2.IsSingleComponent && ds2.Measures.Count > 1)
            {
                throw new VtlOperatorError(expression, this.Name, "Expected single measure structure.");
            }
            if (!ds1.IsSingleComponent && !ds2.IsSingleComponent)
            {
                if (!ds1.IsSupersetOf(ds2, true, false, true) && !ds2.IsSupersetOf(ds1, true, false, true))
                {
                    throw new VtlOperatorError(expression, this.Name, "Datasets doesn't fit.");
                }

                if (!ds1.Measures[0].ValueDomain.DataType.In(BasicDataType.None, BasicDataType.Integer) || ds2.Measures[0].ValueDomain.DataType == BasicDataType.None)
                {
                    structure = ds1.WithAttributesOf(ds2);
                }
                else
                {
                    structure = ds2.WithAttributesOf(ds1);
                }

                return(structure);
            }

            if (!ds1.IsSingleComponent || !ds2.IsSingleComponent)
            {
                structure = ds1.GetCopy().WithAttributesOf(ds2);
                BasicDataType scalarType = ds2.Components[0].ValueDomain.DataType;
                if (!ds2.IsSingleComponent)
                {
                    structure  = ds2.GetCopy().WithAttributesOf(ds1);
                    scalarType = ds1.Components[0].ValueDomain.DataType;
                }

                if (!structure.Measures[0].ValueDomain.DataType.EqualsObj(scalarType))
                {
                    throw new VtlOperatorError(expression, this.Name, "Data types of parameters are not equal.");
                }

                if (structure.Measures[0].ValueDomain.DataType.In(BasicDataType.None, BasicDataType.Integer) && scalarType != BasicDataType.None)
                {
                    structure.Measures[0].ValueDomain = new ValueDomain(scalarType);
                }
                return(structure);
            }

            if (!ds1.Components[0].ValueDomain.DataType.EqualsObj(ds2.Components[0].ValueDomain.DataType))
            {
                throw new VtlOperatorError(expression, this.Name, "Data types of parameters are not equal.");
            }

            if (!ds1.Components[0].ValueDomain.DataType.In(BasicDataType.None, BasicDataType.Integer) || ds2.Components[0].ValueDomain.DataType == BasicDataType.None)
            {
                structure = ds1.WithAttributesOf(ds2);
            }
            else
            {
                structure = ds2.WithAttributesOf(ds1);
            }

            return(structure);
        }
Пример #7
0
        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 (this.Symbol.In("and", "or", "xor"))
            {
                if (expr2 == null)
                {
                    throw new VtlOperatorError(expression, this.Name, "Expected more than one operand.");
                }

                if (expr1.IsScalar)
                {
                    this.ValdiateComponent(expression, expr1.Structure.Components[0]);
                }
                else
                {
                    if (expr1.Structure.Measures.Count > 1)
                    {
                        throw new VtlOperatorError(expression, this.Name, "Expected structure with only one measure.");
                    }
                    this.ValdiateComponent(expression, expr1.Structure.Measures[0]);
                }

                if (expr2.IsScalar)
                {
                    this.ValdiateComponent(expression, expr2.Structure.Components[0]);
                }
                else
                {
                    if (expr2.Structure.Measures.Count > 1)
                    {
                        throw new VtlOperatorError(expression, this.Name, "Expected structure with only one measure.");
                    }
                    this.ValdiateComponent(expression, expr2.Structure.Measures[0]);
                }

                IDataStructure structure;
                IDataStructure ds1 = expr1.Structure.GetCopy();
                IDataStructure ds2 = expr2.Structure.GetCopy();

                if (!ds1.IsSingleComponent)
                {
                    ds1.Measures[0].ValueDomain = new ValueDomain(BasicDataType.Boolean);
                }
                if (!ds2.IsSingleComponent)
                {
                    ds2.Measures[0].ValueDomain = new ValueDomain(BasicDataType.Boolean);
                }

                if (expr1.IsScalar && expr2.IsScalar)
                {
                    structure = this._dsResolver("bool_var", ComponentType.Measure, BasicDataType.Boolean);
                }
                else if (!expr1.IsScalar && expr2.IsScalar)
                {
                    structure = ds1.WithAttributesOf(ds2);
                }
                else if (expr1.IsScalar && !expr2.IsScalar)
                {
                    structure = ds2.WithAttributesOf(ds1);
                }
                else
                {
                    if (ds1.IsSupersetOf(ds2, true, false, true))
                    {
                        structure = ds1.WithAttributesOf(ds2);
                    }
                    else if (ds2.IsSupersetOf(ds1, true, false, true))
                    {
                        structure = ds2.WithAttributesOf(ds1);
                    }
                    else
                    {
                        throw new VtlOperatorError(expression, this.Name, "Datasets doesn't fit.");
                    }
                }

                return(structure);
            }
            else if (this.Symbol == "not")
            {
                if (expr1.IsScalar)
                {
                    this.ValdiateComponent(expression, expr1.Structure.Components[0]);
                }
                else
                {
                    if (expr1.Structure.Measures.Count > 1)
                    {
                        throw new VtlOperatorError(expression, this.Name, "Expected structure with only one measure.");
                    }
                    this.ValdiateComponent(expression, expr1.Structure.Measures[0]);
                }

                IDataStructure ds = expr1.Structure.GetCopy();
                ds.Measures[0].ValueDomain = new ValueDomain(BasicDataType.Boolean);

                return(ds);
            }

            throw new VtlOperatorError(expression, this.Name, $"Unknown operator symbol: \"{this.Symbol}\"");
        }