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)); }
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)); } }
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; }
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); }
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];
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; } }
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 })
public QsiExplainDataManipulationResult(QsiTableStructure table, QsiTableColumn[] affectedColumns, QsiDataValueOperation[] operations) { Table = table; AffectedColumns = affectedColumns; Operations = operations; }
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]));
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)); }
public bool TryGetTable(QsiQualifiedIdentifier identifier, out QsiTableStructure tableStructure) { return(_lookupCache.TryGetValue(identifier, out tableStructure)); }
public void AddDirective(QsiTableStructure directiveTable) { _directives.Add(directiveTable); }
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); }
protected TableDataContext(IAnalyzerContext context, QsiTableStructure table) : base(context) { Table = table; }
public static IEnumerable <QsiTableStructure> FlattenTables(QsiTableStructure structure) { return(FlattenCore(structure, c => c.References, _ => true)); }
public TableDataInsertContext(IAnalyzerContext context, QsiTableStructure table) : base(context, table) { }
public QsiTableAnalysisResult(QsiTableStructure table) { Table = table; }
public void SetTable(QsiQualifiedIdentifier identifier, QsiTableStructure tableStructure) { _lookupCache[identifier] = tableStructure; }
public QsiTableResult(QsiTableStructure table) { Table = table; }
public static IEnumerable <QsiTableStructure> FlattenReferenceTables(QsiTableStructure structure) { return(FlattenCore(structure, c => c.References, x => IsReferenceType(x.Type))); }
protected virtual IEnumerable <DataManipulationTarget> ResolveDataManipulationTargets(QsiTableStructure table) { return(ResolveDataManipulationTargetsCore(table.Columns.SelectMany(ResolveDataManipulationTargetColumns))); }
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];