001package gudusoft.gsqlparser.nodes;
002
003import gudusoft.gsqlparser.*;
004
005/**
006 * @deprecated As of v2.7.4.0, Please use  {@link TJoinExpr} instead.
007 *
008 * A list of join {@link TCustomSqlStatement#joins} represents table sources in following clauses of SQL statement:
009 * <ul>
010 * <li>from clause of select statement.</li>
011 * <li>from clause of delete statement, Specifies an additional FROM clause, This Transact-SQL extension to DELETE allows specifying data from table_source and deleting the corresponding rows from the table in the first FROM clause.</li>
012 * <li>from clause of update statement, Specifies that a table, view, or derived table source is used to provide the criteria for the update operation. </li>
013 * </ul>
014 * <br>Each table source in from clause was treated as a join which is type of {@link TJoin}.
015 * <br>The reason for this design is that we can treat all table sources in from clause in a uniform way.
016 * <br>
017 */
018
019public class TJoin extends TNodeWithAliasClause {
020    private int kind;
021    private TJoin join;
022    private TTable table;
023    private TJoinItemList joinItems = null;
024    private boolean withParen = false;
025
026    private int nestedParen = 0;
027
028    public void setNestedParen(int nestedParen) {
029        if (nestedParen > 0) withParen = true;
030        this.nestedParen = nestedParen;
031    }
032
033    public int getNestedParen() {
034        return nestedParen;
035    }
036
037    public void setWithParen(boolean withParen) {
038        this.withParen = withParen;
039    }
040
041    public boolean isWithParen() {
042
043        return withParen;
044    }
045
046    public void setJoinItems(TJoinItemList joinItems) {
047        this.joinItems = joinItems;
048    }
049
050    public void setJoin(TJoin join) {
051        this.join = join;
052    }
053
054    public void setTable(TTable table) {
055        this.table = table;
056//        if (table == null) return;
057//        if (this.table.getTableType() == ETableSource.subquery){
058//            this.table.getSubquery().setLocation(ESqlClause.join);
059//        }
060    }
061
062    public void setKind(int kind) {
063        this.kind = kind;
064    }
065
066    /**
067     * List of joinItems.
068     * <p>SQL 1:
069     *<blockquote>select f from t1 left join t2 on t1.f1 = t2.f1 right join t3 on t1.f1 = t3.f1</blockquote>
070     * Text in Item 0 will be: left join t2 on t1.f1 = t2.f1
071     * <p>Text in Item 1 will be: right join t3 on t1.f1 = t3.f1
072     * <p>Check {@link TJoinItem} to see how information was organized.
073     * @return
074     */
075    public TJoinItemList getJoinItems() {
076        if (joinItems == null){
077            joinItems = new TJoinItemList();
078        }
079        return joinItems;
080    }
081
082    /**
083     *
084     * @return this join start with another join( (a as a_alias left join a1 on a1.f1 = a_alias.f1) as a_join ) in SQL:
085     * <blockquote>
086     * select a_join.f1
087     * from (a as a_alias left join a1 on a1.f1 = a_alias.f1) as a_join
088     * join b on a_join.f1 = b.f1;
089     * </blockquote>
090     */
091    public TJoin getJoin() {
092        return join;
093    }
094
095    /**
096     *
097     * @return this join start with a table(t1) in SQL:
098     * <blockquote>select f from t1 join t2 on t1.f1 = t2.f1</blockquote>
099     */
100    public TTable getTable() {
101        return table;
102    }
103
104    /**
105     * According to the table source in from clause, there are 3 kinds of join.
106     * <ul>
107     * <li>{@link TBaseType#join_source_fake}, it's a fake join like <blockquote>select f from t1</blockquote>
108     * the whole from clause was represented by this class, you can get text representation of this from clause by using toString() method, it returns "t1" .
109     * and table t1 can be fetch from {@link #getTable}.</li>
110     * <li>{@link TBaseType#join_source_table},<blockquote>select f from t1 join t2 on t1.f1 = t2.f1</blockquote>
111     * the whole from clause was represented by this class, you can get text representation of this from clause by using toString() method,
112     * it returns "t1 join t2 on t1.f1 = t2.f1".
113     * t1 can be fetch from {@link #getTable}.</li>
114     * <li>{@link TBaseType#join_source_join},
115     * <blockquote>
116     * select a_join.f1
117     * from (a as a_alias left join a1 on a1.f1 = a_alias.f1) as a_join
118     * join b on a_join.f1 = b.f1;
119     * </blockquote>
120     * the whole from clause was represented by this class, you can get text representation of this from clause by using toString() method,
121     * it returns "(a as a_alias left join a1 on a1.f1 = a_alias.f1) as a_join join b on a_join.f1 = b.f1".
122     * <p>(a as a_alias left join a1 on a1.f1 = a_alias.f1) can be fetched from {@link #getJoin}.
123     * </li>
124     * </ul>
125     * @return
126     */
127    public int getKind() {
128        return kind;
129    }
130
131    public TJoin(){
132       this.kind = TBaseType.join_source_fake;
133    }
134
135
136    /**
137     *
138     * @return alias of {@link #getJoin}, valid only when {@link #getKind = TBaseType#join_source_join}.
139     * In this SQL, alias is "as a_join"
140     * <blockquote>
141     * select a_join.f1
142     * from (a as a_alias left join a1 on a1.f1 = a_alias.f1) as a_join
143     * join b on a_join.f1 = b.f1;
144     * </blockquote>
145     * <p>But in this SQL, alias is null, "as t1" is the alias of t1.
146     * <blockquote><pre>
147     * select f from t as t1 join t2 on t1.f1 = t2.f1</pre>
148     * </blockquote>
149     */
150    public TAliasClause getAliasClause() {
151
152        return super.getAliasClause();
153    }
154
155    public void accept(TParseTreeVisitor v){
156        v.preVisit(this);
157
158        v.postVisit(this);
159    }
160
161    public void acceptChildren(TParseTreeVisitor v){
162        v.preVisit(this);
163
164
165
166        switch (getKind()){
167            case TBaseType.join_source_fake:
168                getTable().acceptChildren(v);
169                break;
170            case TBaseType.join_source_table:
171            case TBaseType.join_source_join:
172
173                if (getKind() == TBaseType.join_source_table){
174                    getTable().acceptChildren(v);
175                }else if ( getKind() == TBaseType.join_source_join){
176                    getJoin().acceptChildren(v);
177                }
178
179                this.getJoinItems().acceptChildren(v);
180
181
182                break;
183        }
184
185
186        if (getAliasClause() != null){
187            getAliasClause().acceptChildren(v);
188        }
189
190        v.postVisit(this);
191    }
192
193
194}