@@ -224,7 +224,7 @@ class Parser extends BaseParser {
224224 this . setNextToken ( ) ;
225225 this . expectAndSkipWhitespaceAndComments ( ) ;
226226 }
227- const expressions = Array . from ( this . parseExpressions ( AliasOption . REQUIRED ) ) ;
227+ const expressions = this . parseExpressions ( AliasOption . REQUIRED ) ;
228228 if ( expressions . length === 0 ) {
229229 throw new Error ( "Expected expression" ) ;
230230 }
@@ -279,7 +279,7 @@ class Parser extends BaseParser {
279279 this . setNextToken ( ) ;
280280 this . expectAndSkipWhitespaceAndComments ( ) ;
281281 }
282- const expressions = Array . from ( this . parseExpressions ( AliasOption . OPTIONAL ) ) ;
282+ const expressions = this . parseExpressions ( AliasOption . OPTIONAL ) ;
283283 if ( expressions . length === 0 ) {
284284 throw new Error ( "Expected expression" ) ;
285285 }
@@ -393,7 +393,7 @@ class Parser extends BaseParser {
393393 this . expectPreviousTokenToBeWhitespaceOrComment ( ) ;
394394 this . setNextToken ( ) ;
395395 this . expectAndSkipWhitespaceAndComments ( ) ;
396- const expressions = Array . from ( this . parseExpressions ( AliasOption . OPTIONAL ) ) ;
396+ const expressions = this . parseExpressions ( AliasOption . OPTIONAL ) ;
397397 if ( expressions . length === 0 ) {
398398 throw new Error ( "Expected at least one expression" ) ;
399399 }
@@ -903,36 +903,52 @@ class Parser extends BaseParser {
903903 return new OrderBy ( fields ) ;
904904 }
905905
906- private * parseExpressions (
907- alias_option : AliasOption = AliasOption . NOT_ALLOWED
908- ) : IterableIterator < Expression > {
906+ /**
907+ * Parses a comma-separated list of expressions with deferred variable
908+ * registration. Aliases set by earlier expressions in the same clause
909+ * won't shadow variables needed by later expressions
910+ * (e.g. `RETURN a.x AS a, a.y AS b`).
911+ */
912+ private parseExpressions ( alias_option : AliasOption = AliasOption . NOT_ALLOWED ) : Expression [ ] {
913+ const parsed = Array . from ( this . _parseExpressions ( alias_option ) ) ;
914+ for ( const [ expression , variableName ] of parsed ) {
915+ if ( variableName !== null ) {
916+ this . _state . variables . set ( variableName , expression ) ;
917+ }
918+ }
919+ return parsed . map ( ( [ expression ] ) => expression ) ;
920+ }
921+
922+ private * _parseExpressions (
923+ alias_option : AliasOption
924+ ) : IterableIterator < [ Expression , string | null ] > {
909925 while ( true ) {
910926 const expression : Expression | null = this . parseExpression ( ) ;
911- if ( expression !== null ) {
912- const alias = this . parseAlias ( ) ;
913- if ( expression . firstChild ( ) instanceof Reference && alias === null ) {
914- const reference : Reference = expression . firstChild ( ) as Reference ;
915- expression . setAlias ( reference . identifier ) ;
916- this . _state . variables . set ( reference . identifier , expression ) ;
917- } else if (
918- alias_option === AliasOption . REQUIRED &&
919- alias === null &&
920- ! ( expression . firstChild ( ) instanceof Reference )
921- ) {
922- throw new Error ( "Alias required" ) ;
923- } else if ( alias_option === AliasOption . NOT_ALLOWED && alias !== null ) {
924- throw new Error ( "Alias not allowed" ) ;
925- } else if (
926- [ AliasOption . OPTIONAL , AliasOption . REQUIRED ] . includes ( alias_option ) &&
927- alias !== null
928- ) {
929- expression . setAlias ( alias . getAlias ( ) ) ;
930- this . _state . variables . set ( alias . getAlias ( ) , expression ) ;
931- }
932- yield expression ;
933- } else {
927+ if ( expression === null ) {
934928 break ;
935929 }
930+ let variableName : string | null = null ;
931+ const alias = this . parseAlias ( ) ;
932+ if ( expression . firstChild ( ) instanceof Reference && alias === null ) {
933+ const reference : Reference = expression . firstChild ( ) as Reference ;
934+ expression . setAlias ( reference . identifier ) ;
935+ variableName = reference . identifier ;
936+ } else if (
937+ alias_option === AliasOption . REQUIRED &&
938+ alias === null &&
939+ ! ( expression . firstChild ( ) instanceof Reference )
940+ ) {
941+ throw new Error ( "Alias required" ) ;
942+ } else if ( alias_option === AliasOption . NOT_ALLOWED && alias !== null ) {
943+ throw new Error ( "Alias not allowed" ) ;
944+ } else if (
945+ [ AliasOption . OPTIONAL , AliasOption . REQUIRED ] . includes ( alias_option ) &&
946+ alias !== null
947+ ) {
948+ expression . setAlias ( alias . getAlias ( ) ) ;
949+ variableName = alias . getAlias ( ) ;
950+ }
951+ yield [ expression , variableName ] ;
936952 this . skipWhitespaceAndComments ( ) ;
937953 if ( ! this . token . isComma ( ) ) {
938954 break ;
@@ -1360,7 +1376,7 @@ class Parser extends BaseParser {
13601376 this . setNextToken ( ) ;
13611377 this . expectAndSkipWhitespaceAndComments ( ) ;
13621378 }
1363- func . parameters = Array . from ( this . parseExpressions ( AliasOption . NOT_ALLOWED ) ) ;
1379+ func . parameters = this . parseExpressions ( AliasOption . NOT_ALLOWED ) ;
13641380 this . skipWhitespaceAndComments ( ) ;
13651381 if ( ! this . token . isRightParenthesis ( ) ) {
13661382 throw new Error ( "Expected right parenthesis" ) ;
@@ -1394,7 +1410,7 @@ class Parser extends BaseParser {
13941410 this . setNextToken ( ) ; // skip function name
13951411 this . setNextToken ( ) ; // skip left parenthesis
13961412 this . skipWhitespaceAndComments ( ) ;
1397- asyncFunc . parameters = Array . from ( this . parseExpressions ( AliasOption . NOT_ALLOWED ) ) ;
1413+ asyncFunc . parameters = this . parseExpressions ( AliasOption . NOT_ALLOWED ) ;
13981414 this . skipWhitespaceAndComments ( ) ;
13991415 if ( ! this . token . isRightParenthesis ( ) ) {
14001416 throw new Error ( "Expected right parenthesis" ) ;
0 commit comments