001package gudusoft.gsqlparser.nodes;
002
003import gudusoft.gsqlparser.ESqlClause;
004import gudusoft.gsqlparser.ETokenType;
005import gudusoft.gsqlparser.TCustomSqlStatement;
006import gudusoft.gsqlparser.TSourceToken;
007
008public class TXmlTableParameter extends TParseTreeNode {
009    private TSourceToken XQueryString;
010    private TExpression XQueryExpression;
011
012    /**
013     * The XQuery string when it is written as one string literal or one bind variable.
014     *
015     * @return the literal or bind variable token, or null when the XQuery string is any other
016     * expression, such as a concatenation or a function call; {@link #getXQueryExpression()}
017     * returns every form
018     */
019    public TSourceToken getXQueryString() {
020        return XQueryString;
021    }
022
023    /**
024     * The XQuery string argument as an expression. Oracle evaluates this argument as a SQL
025     * string expression, so besides a literal or a bind variable it can be a concatenation,
026     * a function call or a parenthesized expression, for example
027     * {@code XMLTABLE(('"' || REPLACE(str, ',', '","') || '"'))} (Mantis 4960).
028     *
029     * @return the XQuery string expression
030     */
031    public TExpression getXQueryExpression() {
032        return XQueryExpression;
033    }
034
035    public TXMLPassingClause getXmlPassingClause() {
036        return xmlPassingClause;
037    }
038
039    public TColumnDefinitionList getXmlTableColumns() {
040        return xmlTableColumns;
041    }
042
043    private TXMLPassingClause xmlPassingClause;
044    private TColumnDefinitionList xmlTableColumns;
045
046    public void init(Object arg1, Object arg2){
047        if (arg1 instanceof TExpression){
048            XQueryExpression = (TExpression)arg1;
049            XQueryString = singleTokenQueryString(XQueryExpression);
050        }else{
051            XQueryString = (TSourceToken)arg1;
052        }
053        if (arg2 != null){
054            TDummy dummy = (TDummy)arg2;
055            xmlPassingClause = (TXMLPassingClause)dummy.node1;
056            if (dummy.node2 != null){
057                xmlTableColumns = (TColumnDefinitionList)dummy.node2;
058            }
059        }
060    }
061
062    /** The token of a query string written as one string literal or one bind variable, else null. */
063    private static TSourceToken singleTokenQueryString(TExpression expression){
064        TSourceToken token = expression.getStartToken();
065        if ((token == null) || (token != expression.getEndToken())) return null;
066        if ((token.tokentype == ETokenType.ttsqstring) || (token.tokentype == ETokenType.ttbindvar)) return token;
067        return null;
068    }
069
070    public void doParse(TCustomSqlStatement psql, ESqlClause plocation){
071        if (XQueryExpression != null) XQueryExpression.doParse(psql, plocation);
072        if (xmlPassingClause == null || xmlPassingClause.getPassingList() == null) return;
073        TResultColumnList passing = xmlPassingClause.getPassingList();
074        for (int i = 0; i < passing.size(); i++) {
075            TExpression expression = passing.getResultColumn(i).getExpr();
076            if (expression != null) expression.doParse(psql, plocation);
077        }
078    }
079
080    @Override
081    public void accept(TParseTreeVisitor visitor) {
082        visitor.preVisit(this);
083        visitor.postVisit(this);
084    }
085
086    /** Visit input expressions; XQuery aliases and COLUMNS names are definitions. */
087    @Override
088    public void acceptChildren(TParseTreeVisitor visitor) {
089        visitor.preVisit(this);
090        if (XQueryExpression != null) XQueryExpression.acceptChildren(visitor);
091        if (xmlPassingClause != null && xmlPassingClause.getPassingList() != null) {
092            TResultColumnList passing = xmlPassingClause.getPassingList();
093            for (int i = 0; i < passing.size(); i++) {
094                TExpression expression = passing.getResultColumn(i).getExpr();
095                if (expression != null) expression.acceptChildren(visitor);
096            }
097        }
098        visitor.postVisit(this);
099    }
100
101}