@@ -59,6 +59,7 @@ public class BuildMetadataAndInferTypeVisitor : IAwareExpressionVisitor
59
59
60
60
private readonly List < FieldNode > _groupByFields = new ( ) ;
61
61
private readonly List < Type > _nullSuspiciousTypes ;
62
+ private readonly IReadOnlyDictionary < string , string [ ] > _columns ;
62
63
63
64
private int _setKey ;
64
65
private int _schemaFromKey ;
@@ -71,13 +72,17 @@ public class BuildMetadataAndInferTypeVisitor : IAwareExpressionVisitor
71
72
72
73
private Stack < string > Methods { get ; } = new ( ) ;
73
74
74
- public BuildMetadataAndInferTypeVisitor ( ISchemaProvider provider ,
75
- IReadOnlyDictionary < uint , IReadOnlyDictionary < string , string > > positionalEnvironmentVariables )
75
+ public BuildMetadataAndInferTypeVisitor (
76
+ ISchemaProvider provider ,
77
+ IReadOnlyDictionary < uint , IReadOnlyDictionary < string , string > > positionalEnvironmentVariables ,
78
+ IReadOnlyDictionary < string , string [ ] > columns )
76
79
{
77
80
_provider = provider ;
78
81
_positionalEnvironmentVariables = positionalEnvironmentVariables ;
82
+ _columns = columns ;
79
83
_positionalEnvironmentVariablesKey = 0 ;
80
84
_nullSuspiciousTypes = new List < Type > ( ) ;
85
+
81
86
}
82
87
83
88
protected Stack < Node > Nodes { get ; } = new ( ) ;
@@ -447,7 +452,7 @@ public void Visit(IdentifierNode node)
447
452
if ( column == null )
448
453
PrepareAndThrowUnknownColumnExceptionMessage ( node . Name , tableSymbol . GetColumns ( ) ) ;
449
454
450
- Visit ( new AccessColumnNode ( node . Name , string . Empty , column . ColumnType , TextSpan . Empty ) ) ;
455
+ Visit ( new AccessColumnNode ( node . Name , string . Empty , column ? . ColumnType , TextSpan . Empty ) ) ;
451
456
return ;
452
457
}
453
458
@@ -743,24 +748,28 @@ public void Visit(SchemaFromNode node)
743
748
{
744
749
var schema = _provider . GetSchema ( node . Schema ) ;
745
750
751
+ _queryAlias = AliasGenerator . CreateAliasIfEmpty ( node . Alias , _generatedAliases , _schemaFromKey . ToString ( ) ) ;
752
+ _generatedAliases . Add ( _queryAlias ) ;
753
+
746
754
var table = _currentScope . Name != "Desc"
747
- ? schema . GetTableByName ( node . Method , new RuntimeContext (
748
- CancellationToken . None ,
749
- Array . Empty < ISchemaColumn > ( ) ,
750
- _positionalEnvironmentVariables . ContainsKey ( _positionalEnvironmentVariablesKey )
751
- ? _positionalEnvironmentVariables [ _positionalEnvironmentVariablesKey ]
752
- : new Dictionary < string , string > ( ) ,
753
- ( node , Array . Empty < ISchemaColumn > ( ) , AllTrueWhereNode ) ) , _schemaFromArgs . ToArray ( ) )
755
+ ? schema . GetTableByName (
756
+ node . Method ,
757
+ new RuntimeContext (
758
+ CancellationToken . None ,
759
+ _columns [ _queryAlias + _schemaFromKey ] . Select ( ( f , i ) => new SchemaColumn ( f , i , typeof ( object ) ) ) . ToArray ( ) ,
760
+ _positionalEnvironmentVariables . ContainsKey ( _positionalEnvironmentVariablesKey )
761
+ ? _positionalEnvironmentVariables [ _positionalEnvironmentVariablesKey ]
762
+ : new Dictionary < string , string > ( ) ,
763
+ ( node , Array . Empty < ISchemaColumn > ( ) , AllTrueWhereNode )
764
+ ) ,
765
+ _schemaFromArgs . ToArray ( ) )
754
766
: new DynamicTable ( Array . Empty < ISchemaColumn > ( ) ) ;
755
767
756
768
_positionalEnvironmentVariablesKey += 1 ;
757
769
_schemaFromArgs . Clear ( ) ;
758
770
759
771
AddAssembly ( schema . GetType ( ) . Assembly ) ;
760
772
761
- _queryAlias = AliasGenerator . CreateAliasIfEmpty ( node . Alias , _generatedAliases , _schemaFromKey . ToString ( ) ) ;
762
- _generatedAliases . Add ( _queryAlias ) ;
763
-
764
773
var tableSymbol = new TableSymbol ( _queryAlias , schema , table , ! string . IsNullOrEmpty ( node . Alias ) ) ;
765
774
_currentScope . ScopeSymbolTable . AddSymbol ( _queryAlias , tableSymbol ) ;
766
775
_currentScope [ node . Id ] = _queryAlias ;
@@ -774,8 +783,7 @@ public void Visit(SchemaFromNode node)
774
783
if ( ! _usedColumns . ContainsKey ( aliasedSchemaFromNode ) )
775
784
_usedColumns . Add ( aliasedSchemaFromNode , new List < ISchemaColumn > ( ) ) ;
776
785
777
- if ( ! _usedWhereNodes . ContainsKey ( aliasedSchemaFromNode ) )
778
- _usedWhereNodes . Add ( aliasedSchemaFromNode , AllTrueWhereNode ) ;
786
+ _usedWhereNodes . TryAdd ( aliasedSchemaFromNode , AllTrueWhereNode ) ;
779
787
780
788
Nodes . Push ( aliasedSchemaFromNode ) ;
781
789
}
@@ -798,21 +806,35 @@ public void Visit(AliasedFromNode node)
798
806
_queryAlias = AliasGenerator . CreateAliasIfEmpty ( node . Alias , _generatedAliases , _schemaFromKey . ToString ( ) ) ;
799
807
_generatedAliases . Add ( _queryAlias ) ;
800
808
801
- var tableSymbol = new TableSymbol ( _queryAlias , schema , table , ! string . IsNullOrEmpty ( node . Alias ) ) ;
802
- _currentScope . ScopeSymbolTable . AddSymbol ( _queryAlias , tableSymbol ) ;
803
- _currentScope [ node . Id ] = _queryAlias ;
804
-
805
809
var aliasedSchemaFromNode = new Parser . SchemaFromNode ( schemaInfo . Schema , schemaInfo . Method , node . Args ,
806
810
_queryAlias , node . InSourcePosition ) ;
807
811
812
+ var tableSymbol = new TableSymbol (
813
+ _queryAlias ,
814
+ schema ,
815
+ schema . GetTableByName (
816
+ schemaInfo . Method ,
817
+ new RuntimeContext (
818
+ CancellationToken . None ,
819
+ table . Columns ,
820
+ _positionalEnvironmentVariables . ContainsKey ( _positionalEnvironmentVariablesKey )
821
+ ? _positionalEnvironmentVariables [ _positionalEnvironmentVariablesKey ]
822
+ : new Dictionary < string , string > ( ) ,
823
+ ( aliasedSchemaFromNode , Array . Empty < ISchemaColumn > ( ) , AllTrueWhereNode )
824
+ )
825
+ ) ?? table ,
826
+ ! string . IsNullOrEmpty ( node . Alias )
827
+ ) ;
828
+ _currentScope . ScopeSymbolTable . AddSymbol ( _queryAlias , tableSymbol ) ;
829
+ _currentScope [ node . Id ] = _queryAlias ;
830
+
808
831
if ( ! _inferredColumns . ContainsKey ( aliasedSchemaFromNode ) )
809
832
_inferredColumns . Add ( aliasedSchemaFromNode , table . Columns ) ;
810
833
811
834
if ( ! _usedColumns . ContainsKey ( aliasedSchemaFromNode ) )
812
835
_usedColumns . Add ( aliasedSchemaFromNode , new List < ISchemaColumn > ( ) ) ;
813
836
814
- if ( ! _usedWhereNodes . ContainsKey ( aliasedSchemaFromNode ) )
815
- _usedWhereNodes . Add ( aliasedSchemaFromNode , AllTrueWhereNode ) ;
837
+ _usedWhereNodes . TryAdd ( aliasedSchemaFromNode , AllTrueWhereNode ) ;
816
838
817
839
Nodes . Push ( aliasedSchemaFromNode ) ;
818
840
}
@@ -840,7 +862,11 @@ public void Visit(InMemoryTableFromNode node)
840
862
else
841
863
{
842
864
var scope = _currentScope ;
865
+
843
866
while ( scope != null && scope . Name != "CTE" ) scope = scope . Parent ;
867
+
868
+ if ( scope is null )
869
+ throw new NotSupportedException ( $ "Table { node . VariableName } is not defined.") ;
844
870
845
871
tableSymbol = scope . ScopeSymbolTable . GetSymbol < TableSymbol > ( node . VariableName ) ;
846
872
}
@@ -1132,7 +1158,6 @@ private FieldNode[] CreateFields(FieldNode[] oldFields)
1132
1158
1133
1159
for ( var i = reorderedList . Length - 1 ; i >= 0 ; i -- ) reorderedList [ i ] = Nodes . Pop ( ) as FieldNode ;
1134
1160
1135
-
1136
1161
for ( int i = 0 , j = reorderedList . Length , p = 0 ; i < j ; ++ i )
1137
1162
{
1138
1163
var field = reorderedList [ i ] ;
@@ -1443,11 +1468,6 @@ public void SetTheMostInnerIdentifierOfDotNode(IdentifierNode node)
1443
1468
_theMostInnerIdentifier = node ;
1444
1469
}
1445
1470
1446
- public void PushNode ( Node node )
1447
- {
1448
- Nodes . Push ( node ) ;
1449
- }
1450
-
1451
1471
private Type FindGreatestCommonSubtype ( )
1452
1472
{
1453
1473
var types = _nullSuspiciousTypes . Where ( type => type != NullNode . NullType . Instance ) . Select ( StripNullable )
@@ -1484,7 +1504,7 @@ private static void PrepareAndThrowUnknownColumnExceptionMessage(string identifi
1484
1504
var candidatesColumns = columns . Where (
1485
1505
col =>
1486
1506
library . Soundex ( col . ColumnName ) == library . Soundex ( identifier ) ||
1487
- library . LevenshteinDistance ( col . ColumnName , identifier ) . Value < 3 ) . ToArray ( ) ;
1507
+ library . LevenshteinDistance ( col . ColumnName , identifier ) < 3 ) . ToArray ( ) ;
1488
1508
1489
1509
for ( var i = 0 ; i < candidatesColumns . Length - 1 ; i ++ )
1490
1510
{
@@ -1512,7 +1532,7 @@ private static void PrepareAndThrowUnknownPropertyExceptionMessage(string identi
1512
1532
var candidatesProperties = properties . Where (
1513
1533
prop =>
1514
1534
library . Soundex ( prop . Name ) == library . Soundex ( identifier ) ||
1515
- library . LevenshteinDistance ( prop . Name , identifier ) . Value < 3 ) . ToArray ( ) ;
1535
+ library . LevenshteinDistance ( prop . Name , identifier ) < 3 ) . ToArray ( ) ;
1516
1536
1517
1537
for ( var i = 0 ; i < candidatesProperties . Length - 1 ; i ++ )
1518
1538
{
0 commit comments