001package gudusoft.gsqlparser.stmt;
002
003import gudusoft.gsqlparser.EDbVendor;
004import gudusoft.gsqlparser.ESqlStatementType;
005import gudusoft.gsqlparser.TCustomSqlStatement;
006import gudusoft.gsqlparser.nodes.*;
007import gudusoft.gsqlparser.nodes.flink.TFlinkTableProperty;
008
009/**
010 * Statement class for StarRocks CACHE SELECT statement.
011 *
012 * CACHE SELECT is used to warm up the data cache by pre-loading data from tables.
013 *
014 * Syntax:
015 * CACHE SELECT column_name [, ...]
016 * FROM [catalog_name.][db_name.]table_name
017 * [WHERE boolean_expression]
018 * [PROPERTIES("verbose"="true")]
019 */
020public class TStarrocksCacheSelectStmt extends TCustomSqlStatement {
021
022    private TResultColumnList selectList;
023    private TFromTable fromTable;
024    private TExpression cacheWhereClause;
025    private TPTNodeList<TFlinkTableProperty> properties;
026
027    public TStarrocksCacheSelectStmt(EDbVendor dbVendor) {
028        super(dbVendor);
029        sqlstatementtype = ESqlStatementType.sststarrocksCacheSelect;
030    }
031
032    public TResultColumnList getSelectList() {
033        return selectList;
034    }
035
036    public void setSelectList(TResultColumnList selectList) {
037        this.selectList = selectList;
038    }
039
040    public TFromTable getFromTable() {
041        return fromTable;
042    }
043
044    public void setFromTable(TFromTable fromTable) {
045        this.fromTable = fromTable;
046    }
047
048    public TExpression getCacheWhereClause() {
049        return cacheWhereClause;
050    }
051
052    public void setCacheWhereClause(TExpression cacheWhereClause) {
053        this.cacheWhereClause = cacheWhereClause;
054    }
055
056    public TPTNodeList<TFlinkTableProperty> getProperties() {
057        return properties;
058    }
059
060    public void setProperties(TPTNodeList<TFlinkTableProperty> properties) {
061        this.properties = properties;
062    }
063
064    /**
065     * Check if verbose mode is enabled in properties.
066     * @return true if PROPERTIES contains "verbose"="true"
067     */
068    public boolean isVerbose() {
069        if (properties == null) return false;
070        for (int i = 0; i < properties.size(); i++) {
071            TFlinkTableProperty prop = properties.getElement(i);
072            if (prop.getPropertyKey() != null) {
073                String key = prop.getPropertyKey().toString();
074                // Remove quotes from key if present
075                if (key.startsWith("'") && key.endsWith("'")) {
076                    key = key.substring(1, key.length() - 1);
077                } else if (key.startsWith("\"") && key.endsWith("\"")) {
078                    key = key.substring(1, key.length() - 1);
079                }
080                if ("verbose".equalsIgnoreCase(key)) {
081                    if (prop.getPropertyValue() != null) {
082                        String value = prop.getPropertyValue().toString();
083                        // Remove quotes from value if present
084                        if (value.startsWith("'") && value.endsWith("'")) {
085                            value = value.substring(1, value.length() - 1);
086                        } else if (value.startsWith("\"") && value.endsWith("\"")) {
087                            value = value.substring(1, value.length() - 1);
088                        }
089                        return "true".equalsIgnoreCase(value);
090                    }
091                }
092            }
093        }
094        return false;
095    }
096
097    @Override
098    public void accept(TParseTreeVisitor v) {
099        v.preVisit(this);
100        v.postVisit(this);
101    }
102
103    @Override
104    public void acceptChildren(TParseTreeVisitor v) {
105        if (this.selectList != null) {
106            this.selectList.acceptChildren(v);
107        }
108        if (this.fromTable != null) {
109            this.fromTable.accept(v);
110        }
111        if (this.cacheWhereClause != null) {
112            this.cacheWhereClause.accept(v);
113        }
114    }
115
116    @Override
117    public int doParseStatement(TCustomSqlStatement psql) {
118        if (rootNode == null) return -1;
119        super.doParseStatement(psql);
120
121        if (rootNode instanceof TCacheSelectSqlNode) {
122            TCacheSelectSqlNode node = (TCacheSelectSqlNode) rootNode;
123            this.selectList = node.getSelectList();
124            this.fromTable = node.getFromTable();
125            this.cacheWhereClause = node.getWhereClause();
126            this.properties = node.getProperties();
127
128            // Add table to tables list using analyzeFromTable (standard pattern)
129            if (this.fromTable != null) {
130                this.analyzeFromTable(this.fromTable, false);
131            }
132        }
133        return 0;
134    }
135}