diff --git a/.all-contributorsrc b/.all-contributorsrc index 02a86f1818..92b95c9c8c 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -7645,6 +7645,15 @@ "contributions": [ "bug" ] + }, + { + "login": "duursma", + "name": "duursma", + "avatar_url": "https://avatars.githubusercontent.com/u/9378973?v=4", + "profile": "https://github.com/duursma", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index 97c0ea98da..d9cffe897d 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -891,198 +891,201 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d dreaminpast123
dreaminpast123

๐Ÿ› duanyanan
duanyanan

๐Ÿ› dutt-sanjay
dutt-sanjay

๐Ÿ› + duursma
duursma

๐Ÿ’ป dylanleung
dylanleung

๐Ÿ› dzeigler
dzeigler

๐Ÿ› eant60
eant60

๐Ÿ› - ekkirala
ekkirala

๐Ÿ› + ekkirala
ekkirala

๐Ÿ› emersonmoura
emersonmoura

๐Ÿ› emouty
emouty

๐Ÿ’ป eugenepugach
eugenepugach

๐Ÿ› fairy
fairy

๐Ÿ› filiprafalowicz
filiprafalowicz

๐Ÿ’ป flxbl-io
flxbl-io

๐Ÿ’ต - foxmason
foxmason

๐Ÿ› + foxmason
foxmason

๐Ÿ› frankegabor
frankegabor

๐Ÿ› frankl
frankl

๐Ÿ› freafrea
freafrea

๐Ÿ› fsapatin
fsapatin

๐Ÿ› gracia19
gracia19

๐Ÿ› guo fei
guo fei

๐Ÿ› - gurmsc5
gurmsc5

๐Ÿ› + gurmsc5
gurmsc5

๐Ÿ› gwilymatgearset
gwilymatgearset

๐Ÿ’ป ๐Ÿ› haigsn
haigsn

๐Ÿ› hemanshu070
hemanshu070

๐Ÿ› henrik242
henrik242

๐Ÿ› hongpuwu
hongpuwu

๐Ÿ› hvbtup
hvbtup

๐Ÿ’ป ๐Ÿ› - igniti GmbH
igniti GmbH

๐Ÿ› + igniti GmbH
igniti GmbH

๐Ÿ› ilovezfs
ilovezfs

๐Ÿ› itaigilo
itaigilo

๐Ÿ› jakivey32
jakivey32

๐Ÿ› jbennett2091
jbennett2091

๐Ÿ› jcamerin
jcamerin

๐Ÿ› jkeener1
jkeener1

๐Ÿ› - jmetertea
jmetertea

๐Ÿ› + jmetertea
jmetertea

๐Ÿ› johnra2
johnra2

๐Ÿ’ป johnzhao9
johnzhao9

๐Ÿ› josemanuelrolon
josemanuelrolon

๐Ÿ’ป ๐Ÿ› kabroxiko
kabroxiko

๐Ÿ’ป ๐Ÿ› karwer
karwer

๐Ÿ› kaulonline
kaulonline

๐Ÿ› - kdaemonv
kdaemonv

๐Ÿ› + kdaemonv
kdaemonv

๐Ÿ› kdebski85
kdebski85

๐Ÿ› ๐Ÿ’ป kenji21
kenji21

๐Ÿ’ป ๐Ÿ› kfranic
kfranic

๐Ÿ› khalidkh
khalidkh

๐Ÿ› koalalam
koalalam

๐Ÿ› krzyk
krzyk

๐Ÿ› - lasselindqvist
lasselindqvist

๐Ÿ› + lasselindqvist
lasselindqvist

๐Ÿ› lgemeinhardt
lgemeinhardt

๐Ÿ› lihuaib
lihuaib

๐Ÿ› liqingjun123
liqingjun123

๐Ÿ› lonelyma1021
lonelyma1021

๐Ÿ› lpeddy
lpeddy

๐Ÿ› lujiefsi
lujiefsi

๐Ÿ’ป - lukelukes
lukelukes

๐Ÿ’ป + lukelukes
lukelukes

๐Ÿ’ป lyriccoder
lyriccoder

๐Ÿ› marcelmore
marcelmore

๐Ÿ› matchbox
matchbox

๐Ÿ› matthiaskraaz
matthiaskraaz

๐Ÿ› meandonlyme
meandonlyme

๐Ÿ› mikesive
mikesive

๐Ÿ› - milossesic
milossesic

๐Ÿ› + milossesic
milossesic

๐Ÿ› mluckam
mluckam

๐Ÿ’ป ๐Ÿ› mohan-chinnappan-n
mohan-chinnappan-n

๐Ÿ’ป mriddell95
mriddell95

๐Ÿ› mrlzh
mrlzh

๐Ÿ› msloan
msloan

๐Ÿ› mucharlaravalika
mucharlaravalika

๐Ÿ› - mvenneman
mvenneman

๐Ÿ› + mvenneman
mvenneman

๐Ÿ› nareshl119
nareshl119

๐Ÿ› nicolas-harraudeau-sonarsource
nicolas-harraudeau-sonarsource

๐Ÿ› noerremark
noerremark

๐Ÿ› novsirion
novsirion

๐Ÿ› nwcm
nwcm

๐Ÿ“– ๐Ÿ› ๐Ÿ’ป oggboy
oggboy

๐Ÿ› - oinume
oinume

๐Ÿ› + oinume
oinume

๐Ÿ› orimarko
orimarko

๐Ÿ’ป ๐Ÿ› pablogomez2197
pablogomez2197

๐Ÿ› pacvz
pacvz

๐Ÿ’ป pallavi agarwal
pallavi agarwal

๐Ÿ› parksungrin
parksungrin

๐Ÿ› patpatpat123
patpatpat123

๐Ÿ› - patriksevallius
patriksevallius

๐Ÿ› + patriksevallius
patriksevallius

๐Ÿ› pbrajesh1
pbrajesh1

๐Ÿ› phoenix384
phoenix384

๐Ÿ› piotrszymanski-sc
piotrszymanski-sc

๐Ÿ’ป plan3d
plan3d

๐Ÿ› poojasix
poojasix

๐Ÿ› prabhushrikant
prabhushrikant

๐Ÿ› - pujitha8783
pujitha8783

๐Ÿ› + pujitha8783
pujitha8783

๐Ÿ› r-r-a-j
r-r-a-j

๐Ÿ› raghujayjunk
raghujayjunk

๐Ÿ› rajeshveera
rajeshveera

๐Ÿ› rajeswarreddy88
rajeswarreddy88

๐Ÿ› recdevs
recdevs

๐Ÿ› reudismam
reudismam

๐Ÿ’ป ๐Ÿ› - rijkt
rijkt

๐Ÿ› + rijkt
rijkt

๐Ÿ› rillig-tk
rillig-tk

๐Ÿ› rmohan20
rmohan20

๐Ÿ’ป ๐Ÿ› rnveach
rnveach

๐Ÿ› rxmicro
rxmicro

๐Ÿ› ryan-gustafson
ryan-gustafson

๐Ÿ’ป ๐Ÿ› sabi0
sabi0

๐Ÿ› - scais
scais

๐Ÿ› + scais
scais

๐Ÿ› screamingfrog
screamingfrog

๐Ÿ’ต sebbASF
sebbASF

๐Ÿ› sergeygorbaty
sergeygorbaty

๐Ÿ’ป shilko2013
shilko2013

๐Ÿ› shiomiyan
shiomiyan

๐Ÿ“– simeonKondr
simeonKondr

๐Ÿ› - snajberk
snajberk

๐Ÿ› + snajberk
snajberk

๐Ÿ› sniperrifle2004
sniperrifle2004

๐Ÿ› snuyanzin
snuyanzin

๐Ÿ› ๐Ÿ’ป soyodream
soyodream

๐Ÿ› sratz
sratz

๐Ÿ› stonio
stonio

๐Ÿ› sturton
sturton

๐Ÿ’ป ๐Ÿ› - sudharmohan
sudharmohan

๐Ÿ› + sudharmohan
sudharmohan

๐Ÿ› suruchidawar
suruchidawar

๐Ÿ› svenfinitiv
svenfinitiv

๐Ÿ› szymanp23
szymanp23

๐Ÿ› ๐Ÿ’ป tashiscool
tashiscool

๐Ÿ› test-git-hook
test-git-hook

๐Ÿ› testation21
testation21

๐Ÿ’ป ๐Ÿ› - thanosa
thanosa

๐Ÿ› + thanosa
thanosa

๐Ÿ› tiandiyixian
tiandiyixian

๐Ÿ› tobwoerk
tobwoerk

๐Ÿ› tprouvot
tprouvot

๐Ÿ› ๐Ÿ’ป trentchilders
trentchilders

๐Ÿ› triandicAnt
triandicAnt

๐Ÿ› trishul14
trishul14

๐Ÿ› - tsui
tsui

๐Ÿ› + tsui
tsui

๐Ÿ› wangzitom12306
wangzitom12306

๐Ÿ› winhkey
winhkey

๐Ÿ› witherspore
witherspore

๐Ÿ› wjljack
wjljack

๐Ÿ› wuchiuwong
wuchiuwong

๐Ÿ› xingsong
xingsong

๐Ÿ› - xioayuge
xioayuge

๐Ÿ› + xioayuge
xioayuge

๐Ÿ› xnYi9wRezm
xnYi9wRezm

๐Ÿ’ป ๐Ÿ› xuanuy
xuanuy

๐Ÿ› xyf0921
xyf0921

๐Ÿ› yalechen-cyw3
yalechen-cyw3

๐Ÿ› yasuharu-sato
yasuharu-sato

๐Ÿ› zenglian
zenglian

๐Ÿ› - zgrzyt93
zgrzyt93

๐Ÿ’ป ๐Ÿ› + zgrzyt93
zgrzyt93

๐Ÿ’ป ๐Ÿ› zh3ng
zh3ng

๐Ÿ› zt_soft
zt_soft

๐Ÿ› ztt79
ztt79

๐Ÿ› zzzzfeng
zzzzfeng

๐Ÿ› รrpรกd Magosรกnyi
รrpรกd Magosรกnyi

๐Ÿ› ไปป่ดตๆฐ
ไปป่ดตๆฐ

๐Ÿ› + + ่Œ…ๅปถๅฎ‰
่Œ…ๅปถๅฎ‰

๐Ÿ’ป diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index bc1a36ec7a..68fffd2835 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -15,10 +15,13 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€ New and noteworthy ### ๐Ÿ› Fixed Issues +* plsql + * [#5086](https://github.com/pmd/pmd/pull/5086): \[plsql] Fixed issue with missing optional table alias in MERGE usage ### ๐Ÿšจ API Changes ### โœจ External Contributions +* [#5086](https://github.com/pmd/pmd/pull/5086): \[plsql] Fixed issue with missing optional table alias in MERGE usage - [Arjen Duursma](https://github.com/duursma) (@duursma) {% endtocmaker %} diff --git a/pmd-plsql/etc/grammar/PLSQL.jjt b/pmd-plsql/etc/grammar/PLSQL.jjt index e1b14b3992..daf6f68f31 100644 --- a/pmd-plsql/etc/grammar/PLSQL.jjt +++ b/pmd-plsql/etc/grammar/PLSQL.jjt @@ -2709,7 +2709,7 @@ ASTDeleteStatement DeleteStatement() : ASTMergeStatement MergeStatement() : {} { - [ LOOKAHEAD(2) SchemaName() "." ] TableName() [ TableAlias() ] + [ LOOKAHEAD(2) SchemaName() "." ] TableName() [ LOOKAHEAD(1, ID(), { getToken(1).kind != USING } ) TableAlias() ] ( LOOKAHEAD(3) "(" ValuesClause() ")" diff --git a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/MergeStatementIssue1934.pls b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/MergeStatementIssue1934.pls index 555f439f0b..782d8cffba 100644 --- a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/MergeStatementIssue1934.pls +++ b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/MergeStatementIssue1934.pls @@ -13,5 +13,13 @@ BEGIN THEN UPDATE SET b.text = e.text WHEN NOT MATCHED THEN INSERT (ID,KEY1, TEXT,LCE_ID) values (JHS_SEQ.NEXTVAL,'PROM_EDIT_PROM_NR','Edycja promocji nr',123123); + + MERGE INTO b + USING ( SELECT 'PROM_EDIT_PROM_NR' key1,'Edycja promocji nr' text,123123 lce_id FROM dual ) e + ON (b.key1 = e.key1 and b.lce_id=e.lce_id) + WHEN MATCHED + THEN UPDATE SET b.text = e.text + WHEN NOT MATCHED + THEN INSERT (ID,KEY1, TEXT,LCE_ID) values (JHS_SEQ.NEXTVAL,'PROM_EDIT_PROM_NR','Edycja promocji nr',123123); END; / diff --git a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/MergeStatementIssue1934.txt b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/MergeStatementIssue1934.txt index c473d6143c..bda27d276c 100644 --- a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/MergeStatementIssue1934.txt +++ b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/MergeStatementIssue1934.txt @@ -1,12 +1,115 @@ +- Input[@CanonicalImage = null, @ExcludedLinesCount = 0, @ExcludedRangesCount = 0] +- Global[@CanonicalImage = null] +- Block[@CanonicalImage = null] + +- Statement[@CanonicalImage = null] + | +- UnlabelledStatement[@CanonicalImage = null] + | +- MergeStatement[@CanonicalImage = null] + | +- TableName[@CanonicalImage = "JHS_TRANSLATIONS", @Image = "jhs_translations"] + | | +- ID[@CanonicalImage = "JHS_TRANSLATIONS", @Image = "jhs_translations"] + | +- TableAlias[@CanonicalImage = "B", @Image = "b"] + | | +- ID[@CanonicalImage = "B", @Image = "b"] + | +- QueryBlock[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + | | +- SelectList[@CanonicalImage = null] + | | | +- SqlExpression[@CanonicalImage = "\'PROM_EDIT_PROM_NR\'", @Image = "\'PROM_EDIT_PROM_NR\'"] + | | | | +- PrimaryPrefix[@CanonicalImage = "\'PROM_EDIT_PROM_NR\'", @Image = "\'PROM_EDIT_PROM_NR\'", @SelfModifier = false] + | | | | +- Literal[@CanonicalImage = "\'PROM_EDIT_PROM_NR\'", @Image = "\'PROM_EDIT_PROM_NR\'"] + | | | | +- StringLiteral[@CanonicalImage = "\'PROM_EDIT_PROM_NR\'", @Image = "\'PROM_EDIT_PROM_NR\'", @String = "PROM_EDIT_PROM_NR"] + | | | +- ColumnAlias[@CanonicalImage = "KEY1", @Image = "key1"] + | | | | +- ID[@CanonicalImage = "KEY1", @Image = "key1"] + | | | +- SqlExpression[@CanonicalImage = "\'EDYCJA PROMOCJI NR\'", @Image = "\'Edycja promocji nr\'"] + | | | | +- PrimaryPrefix[@CanonicalImage = "\'EDYCJA PROMOCJI NR\'", @Image = "\'Edycja promocji nr\'", @SelfModifier = false] + | | | | +- Literal[@CanonicalImage = "\'EDYCJA PROMOCJI NR\'", @Image = "\'Edycja promocji nr\'"] + | | | | +- StringLiteral[@CanonicalImage = "\'EDYCJA PROMOCJI NR\'", @Image = "\'Edycja promocji nr\'", @String = "Edycja promocji nr"] + | | | +- ColumnAlias[@CanonicalImage = "TEXT", @Image = "text"] + | | | | +- ID[@CanonicalImage = "TEXT", @Image = "text"] + | | | +- SqlExpression[@CanonicalImage = "123123", @Image = "123123"] + | | | | +- PrimaryPrefix[@CanonicalImage = "123123", @Image = "123123", @SelfModifier = false] + | | | | +- Literal[@CanonicalImage = "123123", @Image = "123123"] + | | | | +- NumericLiteral[@CanonicalImage = "123123", @Image = "123123"] + | | | +- ColumnAlias[@CanonicalImage = "LCE_ID", @Image = "lce_id"] + | | | +- ID[@CanonicalImage = "LCE_ID", @Image = "lce_id"] + | | +- FromClause[@CanonicalImage = null] + | | +- TableReference[@CanonicalImage = null] + | | +- TableName[@CanonicalImage = "DUAL", @Image = "dual"] + | | +- ID[@CanonicalImage = "DUAL", @Image = "dual"] + | +- TableAlias[@CanonicalImage = "E", @Image = "e"] + | | +- ID[@CanonicalImage = "E", @Image = "e"] + | +- Condition[@CanonicalImage = null] + | | +- CompoundCondition[@CanonicalImage = null, @Type = "AND"] + | | +- ComparisonCondition[@CanonicalImage = null, @Operator = "="] + | | | +- SqlExpression[@CanonicalImage = "B.KEY1", @Image = "b.key1"] + | | | | +- PrimaryPrefix[@CanonicalImage = "B.KEY1", @Image = "b.key1", @SelfModifier = false] + | | | | +- SimpleExpression[@CanonicalImage = "B.KEY1", @Image = "b.key1"] + | | | | +- TableName[@CanonicalImage = "B", @Image = "b"] + | | | | | +- ID[@CanonicalImage = "B", @Image = "b"] + | | | | +- Column[@CanonicalImage = "KEY1", @Image = "key1"] + | | | | +- ID[@CanonicalImage = "KEY1", @Image = "key1"] + | | | +- SqlExpression[@CanonicalImage = "E.KEY1", @Image = "e.key1"] + | | | +- PrimaryPrefix[@CanonicalImage = "E.KEY1", @Image = "e.key1", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "E.KEY1", @Image = "e.key1"] + | | | +- TableName[@CanonicalImage = "E", @Image = "e"] + | | | | +- ID[@CanonicalImage = "E", @Image = "e"] + | | | +- Column[@CanonicalImage = "KEY1", @Image = "key1"] + | | | +- ID[@CanonicalImage = "KEY1", @Image = "key1"] + | | +- Condition[@CanonicalImage = null] + | | +- CompoundCondition[@CanonicalImage = null, @Type = null] + | | +- ComparisonCondition[@CanonicalImage = null, @Operator = "="] + | | +- SqlExpression[@CanonicalImage = "B.LCE_ID", @Image = "b.lce_id"] + | | | +- PrimaryPrefix[@CanonicalImage = "B.LCE_ID", @Image = "b.lce_id", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "B.LCE_ID", @Image = "b.lce_id"] + | | | +- TableName[@CanonicalImage = "B", @Image = "b"] + | | | | +- ID[@CanonicalImage = "B", @Image = "b"] + | | | +- Column[@CanonicalImage = "LCE_ID", @Image = "lce_id"] + | | | +- ID[@CanonicalImage = "LCE_ID", @Image = "lce_id"] + | | +- SqlExpression[@CanonicalImage = "E.LCE_ID", @Image = "e.lce_id"] + | | +- PrimaryPrefix[@CanonicalImage = "E.LCE_ID", @Image = "e.lce_id", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "E.LCE_ID", @Image = "e.lce_id"] + | | +- TableName[@CanonicalImage = "E", @Image = "e"] + | | | +- ID[@CanonicalImage = "E", @Image = "e"] + | | +- Column[@CanonicalImage = "LCE_ID", @Image = "lce_id"] + | | +- ID[@CanonicalImage = "LCE_ID", @Image = "lce_id"] + | +- MergeUpdateClause[@CanonicalImage = null] + | | +- TableName[@CanonicalImage = "B", @Image = "b"] + | | | +- ID[@CanonicalImage = "B", @Image = "b"] + | | +- Column[@CanonicalImage = "TEXT", @Image = "text"] + | | | +- ID[@CanonicalImage = "TEXT", @Image = "text"] + | | +- Expression[@CanonicalImage = "E.TEXT", @Image = "e.text"] + | | +- PrimaryPrefix[@CanonicalImage = "E.TEXT", @Image = "e.text", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "E.TEXT", @Image = "e.text"] + | | +- TableName[@CanonicalImage = "E", @Image = "e"] + | | | +- ID[@CanonicalImage = "E", @Image = "e"] + | | +- Column[@CanonicalImage = "TEXT", @Image = "text"] + | | +- ID[@CanonicalImage = "TEXT", @Image = "text"] + | +- MergeInsertClause[@CanonicalImage = null] + | +- Column[@CanonicalImage = "ID", @Image = "ID"] + | | +- ID[@CanonicalImage = "ID", @Image = "ID"] + | +- Column[@CanonicalImage = "KEY1", @Image = "KEY1"] + | | +- ID[@CanonicalImage = "KEY1", @Image = "KEY1"] + | +- Column[@CanonicalImage = "TEXT", @Image = "TEXT"] + | | +- ID[@CanonicalImage = "TEXT", @Image = "TEXT"] + | +- Column[@CanonicalImage = "LCE_ID", @Image = "LCE_ID"] + | | +- ID[@CanonicalImage = "LCE_ID", @Image = "LCE_ID"] + | +- ValuesClause[@CanonicalImage = null] + | +- Expression[@CanonicalImage = "", @Image = ""] + | | +- PrimaryPrefix[@CanonicalImage = "", @Image = "", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "", @Image = ""] + | | +- ID[@CanonicalImage = "JHS_SEQ", @Image = "JHS_SEQ"] + | +- Expression[@CanonicalImage = "\'PROM_EDIT_PROM_NR\'", @Image = "\'PROM_EDIT_PROM_NR\'"] + | | +- PrimaryPrefix[@CanonicalImage = "\'PROM_EDIT_PROM_NR\'", @Image = "\'PROM_EDIT_PROM_NR\'", @SelfModifier = false] + | | +- Literal[@CanonicalImage = "\'PROM_EDIT_PROM_NR\'", @Image = "\'PROM_EDIT_PROM_NR\'"] + | | +- StringLiteral[@CanonicalImage = "\'PROM_EDIT_PROM_NR\'", @Image = "\'PROM_EDIT_PROM_NR\'", @String = "PROM_EDIT_PROM_NR"] + | +- Expression[@CanonicalImage = "\'EDYCJA PROMOCJI NR\'", @Image = "\'Edycja promocji nr\'"] + | | +- PrimaryPrefix[@CanonicalImage = "\'EDYCJA PROMOCJI NR\'", @Image = "\'Edycja promocji nr\'", @SelfModifier = false] + | | +- Literal[@CanonicalImage = "\'EDYCJA PROMOCJI NR\'", @Image = "\'Edycja promocji nr\'"] + | | +- StringLiteral[@CanonicalImage = "\'EDYCJA PROMOCJI NR\'", @Image = "\'Edycja promocji nr\'", @String = "Edycja promocji nr"] + | +- Expression[@CanonicalImage = "123123", @Image = "123123"] + | +- PrimaryPrefix[@CanonicalImage = "123123", @Image = "123123", @SelfModifier = false] + | +- Literal[@CanonicalImage = "123123", @Image = "123123"] + | +- NumericLiteral[@CanonicalImage = "123123", @Image = "123123"] +- Statement[@CanonicalImage = null] +- UnlabelledStatement[@CanonicalImage = null] +- MergeStatement[@CanonicalImage = null] - +- TableName[@CanonicalImage = "JHS_TRANSLATIONS", @Image = "jhs_translations"] - | +- ID[@CanonicalImage = "JHS_TRANSLATIONS", @Image = "jhs_translations"] - +- TableAlias[@CanonicalImage = "B", @Image = "b"] + +- TableName[@CanonicalImage = "B", @Image = "b"] | +- ID[@CanonicalImage = "B", @Image = "b"] +- QueryBlock[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] | +- SelectList[@CanonicalImage = null]