Ejemplo n.º 1
0
        protected override async ValueTask <IQsiAnalysisResult> OnExecute(IAnalyzerContext context)
        {
            if (context.Tree is CqlDerivedTableNode {
                IsJson : true
            } cqlTableNode)
            {
                using var scope = new TableCompileContext(context);
                var table = await BuildTableStructure(scope, cqlTableNode);

                var jsonTable = new QsiTableStructure
                {
                    Identifier = table.Identifier,
                    Type       = table.Type,
                    IsSystem   = table.IsSystem
                };

                jsonTable.References.AddRange(table.References);

                var jsonColumn = jsonTable.NewColumn();

                jsonColumn.Name = new QsiIdentifier("[json]", false);
                jsonColumn.References.AddRange(table.Columns);

                return(new CqlJsonTableAnalysisResult(jsonTable));
            }

            return(await base.OnExecute(context));
        }
Ejemplo n.º 2
0
        protected virtual ValueTask <QsiTableStructure> BuildInlineDerivedTableStructure(TableCompileContext context, IQsiInlineDerivedTableNode table)
        {
            context.ThrowIfCancellationRequested();

            var alias = table.Alias?.Name;

            if (alias == null &&
                table.Parent is IQsiDerivedColumnNode &&
                !context.Options.AllowNoAliasInDerivedTable)
            {
                throw new QsiException(QsiError.NoAlias);
            }

            var declaredTable = new QsiTableStructure
            {
                Type       = QsiTableType.Inline,
                Identifier = alias == null ? null : new QsiQualifiedIdentifier(alias)
            };

            int?columnCount = null;

            switch (table.Columns)
            {
            case null:
            case var cd when cd.All(c => c is IQsiAllColumnNode {
                    Path: null
                }) :
                // Skip
                break;
 protected void AddColumns(QsiTableStructure table, params string[] names)
 {
     foreach (var name in names)
     {
         var c = table.NewColumn();
         c.Name = new QsiIdentifier(name, IdentifierUtility.IsEscaped(name));
     }
 }
Ejemplo n.º 4
0
        protected bool Match(IAnalyzerContext context, QsiTableStructure table, QsiQualifiedIdentifier identifier)
        {
            if (!table.HasIdentifier)
            {
                return(false);
            }

            // * case - Explicit access
            // ┌──────────────────────────────────────────────────────────┐
            // │ SELECT sakila.actor.column FROM sakila.actor             │
            // │        ▔▔▔▔▔▔^▔▔▔▔▔      ==     ▔▔▔▔▔▔^▔▔▔▔▔             │
            // │         └-> identifier(2)        └-> table.Identifier(2) │
            // └──────────────────────────────────────────────────────────┘

            if (Match(table.Identifier, identifier))
            {
                return(true);
            }

            // * case - 2 Level implicit access
            // ┌──────────────────────────────────────────────────────────┐
            // │ SELECT actor.column FROM sakila.actor                    │
            // │        ▔▔▔▔▔      <       ▔▔▔▔▔^▔▔▔▔▔                    │
            // │         └-> identifier(1)  └-> table.Identifier(2)       │
            // └──────────────────────────────────────────────────────────┘

            // * case - 3 Level implicit access
            // ┌──────────────────────────────────────────────────────────┐
            // │ SELECT sakila.actor.column FROM db.sakila.actor          │
            // │        ▔▔▔▔▔▔^▔▔▔▔▔       <     ▔▔^▔▔▔▔▔▔^▔▔▔▔▔          │
            // │         └-> identifier(2)        └-> table.Identifier(3) │
            // └──────────────────────────────────────────────────────────┘

            if (context.Options.UseExplicitRelationAccess)
            {
                return(false);
            }

            if (!QsiUtility.IsReferenceType(table.Type))
            {
                return(false);
            }

            if (table.Identifier.Level <= identifier.Level)
            {
                return(false);
            }

            QsiIdentifier[] partialIdentifiers = table.Identifier[^ identifier.Level..];
        public DataManipulationTarget(QsiTableStructure table, DataManipulationTargetColumnPivot[] pivots)
        {
            if (table.Type != QsiTableType.Table)
            {
                throw new ArgumentException(nameof(table));
            }

            if (pivots.Length != table.Columns.Count)
            {
                throw new ArgumentException(nameof(pivots));
            }

            Table        = table;
            ColumnPivots = pivots;
        }
Ejemplo n.º 6
0
        private QsiTableStructure CreatePseudoTable()
        {
            var table = new QsiTableStructure
            {
                Identifier = new QsiQualifiedIdentifier(new QsiIdentifier("PseudoColumns", false))
            };

            foreach (var name in OraclePseudoColumn.Names)
            {
                var c = table.NewColumn();
                c.Name = new QsiIdentifier(name, false);
            }

            return(table);
        }
Ejemplo n.º 7
0
        private IEnumerable <ColumnPlan> CompileColumnPlan(IAnalyzerContext context, QsiTableStructure table, IQsiColumnsDeclarationNode columns)
        {
            if (columns.Columns.All(c => c is IQsiAllColumnNode))
            {
                return(table.Columns.Select(c => new ColumnPlan(c.Name)));
            }

            var plans = new Dictionary <QsiIdentifier, ColumnPlan>(IdentifierComparer);

            foreach (var column in columns)
            {
                QsiIdentifier identifier;
                ISelector[]   selectors = null;

                switch (column)
                {
                case IQsiDeclaredColumnNode declaredColumn:
                {
                    identifier = declaredColumn.Name[^ 1];
Ejemplo n.º 8
0
        protected virtual async ValueTask <QsiTableStructure> BuildRecursiveCompositeTableStructure(TableCompileContext context, IQsiDerivedTableNode table, IQsiCompositeTableNode source)
        {
            context.ThrowIfCancellationRequested();

            var declaredTable = new QsiTableStructure
            {
                Type       = QsiTableType.Derived,
                Identifier = new QsiQualifiedIdentifier(table.Alias.Name)
            };

            int sourceOffset = 0;
            var structures   = new List <QsiTableStructure>(source.Sources.Length);

            if (table.Columns.Any(c => c is not IQsiAllColumnNode))
            {
                foreach (var columnNode in table.Columns.Cast <IQsiSequentialColumnNode>())
                {
                    var column = declaredTable.NewColumn();
                    column.Name = columnNode.Alias.Name;
                }
            }
Ejemplo n.º 9
0
        private ValueTask <QsiTableStructure> BuildImpalaValuesTableStructure(TableCompileContext context, ImpalaValuesTableNode table)
        {
            if (table.Rows.Count == 0)
            {
                throw new QsiException(QsiError.Syntax);
            }

            var structure = new QsiTableStructure
            {
                Type = QsiTableType.Inline
            };

            var columnCount = table.Rows[0].ColumnValues.Count;

            foreach (var value in table.Rows[0].ColumnValues)
            {
                var column = structure.NewColumn();

                if (value is IQsiColumnExpressionNode {
                    Column: IQsiDerivedColumnNode {
                        Alias: { }
                    } derivedColumnNode
                })
Ejemplo n.º 10
0
 public QsiExplainDataManipulationResult(QsiTableStructure table, QsiTableColumn[] affectedColumns, QsiDataValueOperation[] operations)
 {
     Table           = table;
     AffectedColumns = affectedColumns;
     Operations      = operations;
 }
Ejemplo n.º 11
0
        protected virtual IEnumerable <DataManipulationTarget> ResolveDataManipulationTargets(QsiTableStructure table, IEnumerable <QsiQualifiedIdentifier> columnNames)
        {
            QsiTableColumn[] columnsBuffer = table.Columns.ToArray();

            IEnumerable <DataManipulationTargetColumnPivot> rawPivots = columnNames
                                                                        .SelectMany((declaredName, i) =>
            {
                var index = columnsBuffer.FindIndex(c => c != null && Match(c.Name, declaredName[^ 1]));
Ejemplo n.º 12
0
        protected virtual ValueTask <QsiTableStructure> BuildInlineDerivedTableStructure(TableCompileContext context, IQsiInlineDerivedTableNode table)
        {
            context.ThrowIfCancellationRequested();

            var alias = table.Alias?.Name;

            if (alias == null &&
                table.Parent is IQsiDerivedColumnNode &&
                !context.Options.AllowNoAliasInDerivedTable)
            {
                throw new QsiException(QsiError.NoAlias);
            }

            var declaredTable = new QsiTableStructure
            {
                Type       = QsiTableType.Inline,
                Identifier = alias == null ? null : new QsiQualifiedIdentifier(alias)
            };

            int?columnCount = null;

            switch (table.Columns)
            {
            case null:
            case var cd when cd.All(c => c is IQsiAllColumnNode { Path: null } all) :
                // Skip
                break;

            case var cd when cd.TryCast(out IQsiSequentialColumnNode[] sequentialColumns):
                foreach (var column in sequentialColumns)
                {
                    var c = declaredTable.NewColumn();

                    c.Name = column.Alias.Name;
                }

                columnCount = sequentialColumns.Length;
                break;

            default:
                throw new NotSupportedException("Not supported columns in inline derived table.");
            }

            // Skip trace columns in expression.
            // Because don't know the possibility of declaring a referenceable column in the expression.
            // ISSUE: row.ColumnValues
            foreach (var row in table.Rows ?? Enumerable.Empty <IQsiRowValueExpressionNode>())
            {
                if (!columnCount.HasValue)
                {
                    columnCount = row.ColumnValues.Length;
                }
                else if (columnCount != row.ColumnValues.Length)
                {
                    throw new QsiException(QsiError.DifferentColumnsCount);
                }
            }

            if ((columnCount ?? 0) == 0)
            {
                if (!context.Options.AllowEmptyColumnsInInline)
                {
                    throw new QsiException(QsiError.NoColumnsSpecified, alias);
                }

                columnCount = 0;
            }

            if (declaredTable.Columns.Count != columnCount)
            {
                for (int i = 0; i < columnCount; i++)
                {
                    declaredTable.NewColumn();
                }
            }

            return(new ValueTask <QsiTableStructure>(declaredTable));
        }
Ejemplo n.º 13
0
 public bool TryGetTable(QsiQualifiedIdentifier identifier, out QsiTableStructure tableStructure)
 {
     return(_lookupCache.TryGetValue(identifier, out tableStructure));
 }
Ejemplo n.º 14
0
 public void AddDirective(QsiTableStructure directiveTable)
 {
     _directives.Add(directiveTable);
 }
Ejemplo n.º 15
0
        protected virtual async ValueTask <QsiTableStructure> BuildDerivedTableStructure(TableCompileContext context, IQsiDerivedTableNode table)
        {
            context.ThrowIfCancellationRequested();

            using var scopedContext = new TableCompileContext(context);

            // Directives

            if (table.Directives?.Tables?.Length > 0)
            {
                await BuildDirectives(scopedContext, table.Directives);
            }

            // Table Source

            var alias = table.Alias?.Name;

            if (alias == null &&
                table.Parent is IQsiDerivedColumnNode &&
                !context.Options.AllowNoAliasInDerivedTable)
            {
                throw new QsiException(QsiError.NoAlias);
            }

            if (table.Source is IQsiJoinedTableNode joinedTableNode)
            {
                scopedContext.SourceTable = await BuildJoinedTableStructure(scopedContext, joinedTableNode);
            }
            else if (table.Source != null)
            {
                using var sourceContext   = new TableCompileContext(scopedContext);
                scopedContext.SourceTable = await BuildTableStructure(scopedContext, table.Source);
            }

            var declaredTable = new QsiTableStructure
            {
                Type       = QsiTableType.Derived,
                Identifier = alias == null ? null : new QsiQualifiedIdentifier(alias)
            };

            if (scopedContext.SourceTable != null)
            {
                declaredTable.References.Add(scopedContext.SourceTable);
            }

            var columns = table.Columns;

            if (columns == null || columns.Count == 0)
            {
                if (!context.Options.AllowEmptyColumnsInSelect)
                {
                    throw new QsiException(QsiError.Syntax);
                }
            }
            else if (columns.TryCast(out IQsiSequentialColumnNode[] sequentialColumns))
            {
                // Sequential columns definition

                if (scopedContext.SourceTable == null)
                {
                    throw new QsiException(QsiError.NoTablesUsed);
                }

                var columnType = sequentialColumns[0].ColumnType;
                QsiTableColumn[] allColumns = scopedContext.SourceTable.VisibleColumns.ToArray();
                int columnLength            = allColumns.Length;

                if (sequentialColumns.Length > allColumns.Length)
                {
                    throw new QsiException(QsiError.SpecifiesMoreColumnNames);
                }

                if (columnType == QsiSequentialColumnType.Default)
                {
                    if (sequentialColumns.Length != allColumns.Length)
                    {
                        throw new QsiException(QsiError.DifferentColumnsCount);
                    }

                    columnLength = sequentialColumns.Length;
                }

                for (int i = 0; i < columnLength; i++)
                {
                    var column         = allColumns[i];
                    var declaredColumn = declaredTable.NewColumn();

                    declaredColumn.Name = i < sequentialColumns.Length ? sequentialColumns[i].Alias?.Name : column.Name;
                    declaredColumn.References.Add(column);
                }
            }
            else
            {
                // Compund columns definition

                foreach (var column in columns)
                {
                    IEnumerable <QsiTableColumn> resolvedColumns = ResolveColumns(scopedContext, column);

                    switch (column)
                    {
                    case IQsiDerivedColumnNode derivedColum:
                    {
                        var declaredColumn = declaredTable.NewColumn();

                        declaredColumn.Name         = derivedColum.Alias?.Name;
                        declaredColumn.IsExpression = derivedColum.IsExpression;
                        declaredColumn.References.AddRange(resolvedColumns);
                        break;
                    }

                    case IQsiBindingColumnNode bindingColumn:
                    {
                        var declaredColumn = declaredTable.NewColumn();
                        declaredColumn.Name      = new QsiIdentifier(bindingColumn.Id, false);
                        declaredColumn.IsBinding = true;
                        break;
                    }

                    default:
                    {
                        foreach (var c in resolvedColumns)
                        {
                            var declaredColumn = declaredTable.NewColumn();

                            declaredColumn.Name = c.Name;
                            declaredColumn.References.Add(c);
                        }

                        break;
                    }
                    }
                }
            }

            return(declaredTable);
        }
Ejemplo n.º 16
0
 protected TableDataContext(IAnalyzerContext context, QsiTableStructure table) : base(context)
 {
     Table = table;
 }
Ejemplo n.º 17
0
 public static IEnumerable <QsiTableStructure> FlattenTables(QsiTableStructure structure)
 {
     return(FlattenCore(structure, c => c.References, _ => true));
 }
 public TableDataInsertContext(IAnalyzerContext context, QsiTableStructure table) : base(context, table)
 {
 }
Ejemplo n.º 19
0
 public QsiTableAnalysisResult(QsiTableStructure table)
 {
     Table = table;
 }
Ejemplo n.º 20
0
 public void SetTable(QsiQualifiedIdentifier identifier, QsiTableStructure tableStructure)
 {
     _lookupCache[identifier] = tableStructure;
 }
Ejemplo n.º 21
0
 public QsiTableResult(QsiTableStructure table)
 {
     Table = table;
 }
Ejemplo n.º 22
0
 public static IEnumerable <QsiTableStructure> FlattenReferenceTables(QsiTableStructure structure)
 {
     return(FlattenCore(structure, c => c.References, x => IsReferenceType(x.Type)));
 }
Ejemplo n.º 23
0
 protected virtual IEnumerable <DataManipulationTarget> ResolveDataManipulationTargets(QsiTableStructure table)
 {
     return(ResolveDataManipulationTargetsCore(table.Columns.SelectMany(ResolveDataManipulationTargetColumns)));
 }
Ejemplo n.º 24
0
 public PrimarSqlJsonTableResult(QsiTableStructure table) : base(table)
 {
 }
 public CqlJsonTableAnalysisResult(QsiTableStructure table) : base(table)
 {
 }
 private void PatchDynamicTable(QsiTableStructure structure, IDynamicTableNode dynamicTableNode)
 {
     foreach (var dynamicColumn in dynamicTableNode.DynamicColumns.Columns.Cast <PDynamicDeclaredColumnNode>())
     {
         var column = structure.NewColumn();
         column.Name      = dynamicColumn.Name[^ 1];