001package gudusoft.gsqlparser.stmt.snowflake;
002
003
004import gudusoft.gsqlparser.EDbVendor;
005import gudusoft.gsqlparser.ESqlClause;
006import gudusoft.gsqlparser.ESqlStatementType;
007import gudusoft.gsqlparser.TCustomSqlStatement;
008import gudusoft.gsqlparser.ETableSource;
009import gudusoft.gsqlparser.nodes.TCreateTableOption;
010import gudusoft.gsqlparser.nodes.TObjectName;
011import gudusoft.gsqlparser.nodes.TObjectNameList;
012import gudusoft.gsqlparser.nodes.TParseTreeVisitor;
013import gudusoft.gsqlparser.nodes.TStageLocation;
014import gudusoft.gsqlparser.nodes.TTable;
015import gudusoft.gsqlparser.nodes.snowflake.TCopyIntoNode;
016import gudusoft.gsqlparser.nodes.snowflake.TStageReference;
017import gudusoft.gsqlparser.stmt.TSelectSqlStatement;
018
019import java.util.ArrayList;
020
021public class TSnowflakeCopyIntoStmt extends TCustomSqlStatement {
022
023    private ArrayList<String> fileList = new ArrayList<>();
024
025
026    public ArrayList<String> getFileList() {
027        return fileList;
028    }
029
030    private String fileFormatName = null;
031    private String fileFormatType = null;
032
033    public void setFileFormatName(String fileFormatName) {
034        this.fileFormatName = fileFormatName;
035    }
036
037    public void setFileFormatType(String fileFormatType) {
038        this.fileFormatType = fileFormatType;
039    }
040
041    public String getFileFormatName() {
042        return fileFormatName;
043    }
044
045    public String getFileFormatType() {
046        return fileFormatType;
047    }
048
049    public static int COPY_INTO_TABLE = 0;
050    public static int COPY_INTO_LOCATION = 1;
051
052    private String regex_pattern;
053
054    public void setRegex_pattern(String regex_pattern) {
055        this.regex_pattern = regex_pattern;
056    }
057
058    public String getRegex_pattern() {
059        return regex_pattern;
060    }
061
062    private int copyIntoType = TSnowflakeCopyIntoStmt.COPY_INTO_TABLE;
063
064    public int getCopyIntoType() {
065        return copyIntoType;
066    }
067
068    private TStageLocation stageLocation;
069
070    public TStageLocation getStageLocation() {
071        return stageLocation;
072    }
073
074    private TObjectName tableName;
075    private TSelectSqlStatement subQuery;
076    public TSnowflakeCopyIntoStmt(EDbVendor dbvendor) {
077        super(dbvendor);
078        sqlstatementtype = ESqlStatementType.sstCopyInto;
079    }
080
081    public void setTableName(TObjectName tableName) {
082        this.tableName = tableName;
083    }
084
085    public void setSubQuery(TSelectSqlStatement subQuery) {
086        this.subQuery = subQuery;
087    }
088
089    public TObjectName getTableName() {
090
091        return tableName;
092    }
093
094    public TSelectSqlStatement getSubQuery() {
095        return subQuery;
096    }
097
098    private TObjectName fromSourceLocation;
099    public TObjectName getFromSourceLocation() {
100        return fromSourceLocation;
101    }
102
103    private TObjectNameList tableColumnList;
104
105    public void setTableColumnList(TObjectNameList tableColumnList) {
106        this.tableColumnList = tableColumnList;
107    }
108
109    public TObjectNameList getTableColumnList() {
110        return tableColumnList;
111    }
112
113
114    public int doParseStatement(TCustomSqlStatement psql) {
115        if (rootNode == null) return -1;
116        super.doParseStatement(psql);
117        TCopyIntoNode node = (TCopyIntoNode)(rootNode);
118        tableName = node.getTableName();
119        this.copyIntoType = node.getCopyIntoType();
120        this.stageLocation = node.getStageLocation();
121
122        if (node.getSubquery() != null){
123            subQuery = new TSelectSqlStatement(this.dbvendor);
124            subQuery.rootNode = node.getSubquery();
125            subQuery.doParseStatement(this);
126
127            // When the stage location is inside the subquery's FROM clause
128            // (e.g., COPY INTO t FROM (SELECT ... FROM @stage/path)),
129            // propagate it to the COPY INTO statement for API accessibility.
130            if (this.stageLocation == null && subQuery.getTables() != null) {
131                for (int i = 0; i < subQuery.getTables().size(); i++) {
132                    TTable table = subQuery.getTables().getTable(i);
133                    if (table.getTableType() == ETableSource.stageReference
134                            && table.getStageReference() != null) {
135                        TStageReference ref = table.getStageReference();
136                        this.stageLocation = new TStageLocation();
137                        this.stageLocation.setStage(true);
138                        if (ref.getStageName() != null) {
139                            String name = ref.getStageName().toString();
140                            if (name.startsWith("~")) {
141                                this.stageLocation.init(TStageLocation.EStageLocationType.internalUser);
142                            } else if (name.startsWith("%")) {
143                                this.stageLocation.init(TStageLocation.EStageLocationType.internalTable);
144                                TObjectName tblName = new TObjectName();
145                                tblName.setString(name.substring(1));
146                                this.stageLocation.setTableName(tblName);
147                            } else {
148                                this.stageLocation.init(TStageLocation.EStageLocationType.internalNamed, ref.getStageName());
149                            }
150                        }
151                        if (ref.getStagePath() != null) {
152                            this.stageLocation.setPath(ref.getStagePath());
153                        }
154                        break;
155                    }
156                }
157            }
158        }
159
160        ArrayList<TCreateTableOption> tableOptions = node.tableOptions;
161        if (tableOptions != null){
162            for(int i=0;i<tableOptions.size();i++){
163                tableOptions.get(i).doParse(this, ESqlClause.unknown);
164            }
165        }
166
167        fromSourceLocation = node.getFromSourceLocation();
168        tableColumnList = node.getTableColumnList();
169
170        return 0;
171    }
172
173    public void accept(TParseTreeVisitor v){
174        v.preVisit(this);
175        v.postVisit(this);
176    }
177
178    public void acceptChildren(TParseTreeVisitor v){
179        v.preVisit(this);
180        if (this.subQuery != null){
181            this.subQuery.acceptChildren(v);
182        }
183        v.postVisit(this);
184    }
185
186}