001package gudusoft.gsqlparser.stmt;
002
003import gudusoft.gsqlparser.*;
004import gudusoft.gsqlparser.nodes.*;
005import gudusoft.gsqlparser.nodes.EHiveInsertType;
006import gudusoft.gsqlparser.nodes.EOnConflictActionType;
007import gudusoft.gsqlparser.nodes.oracle.TErrorLoggingClause;
008import gudusoft.gsqlparser.stmt.mssql.TMssqlExecute;
009
010import java.util.ArrayList;
011
012/**
013 * SQL insert statement.
014 * <br>
015 * <br> {@link #getTargetTable} returns the table or view that receive the data.
016 * <br> {@link #getColumnList()} returns the list of columns in target table if specified.
017 * <br> Usually, the data comes from a value clause, you can get those values from {@link #getValues()}.
018 * <br> Always checking {@link #getInsertSource} before fetch the data source which may various from value clause
019 * to subquery and other forms. Below are some data source types:
020 * <ul>
021 *     <li>{@link EInsertSource#values} -&gt; {@link #getValues()}</li>
022 *     <li>{@link EInsertSource#subquery} -&gt; {@link #getSubQuery()}</li>
023 * </ul>
024 *
025 * <br>Examples:
026 * <pre>
027 * INSERT INTO Production.UnitMeasure (Name, UnitMeasureCode,ModifiedDate)
028 * VALUES (N'Square Yards', N'Y2', GETDATE());
029 * </pre>
030 * Table name: Production.UnitMeasure. Fetched from {@link #getTargetTable} or the first element of {@link #tables}
031 * <br>column list: (Name, UnitMeasureCode,ModifiedDate). Fetch from {@link #getColumnList}
032 * <br>value list: (N'Square Yards', N'Y2', GETDATE()). Fetch from {@link #getValues}
033 * <br>
034 * <pre>
035 * INSERT INTO dbo.EmployeeSales
036 * SELECT 'SELECT', sp.BusinessEntityID, c.LastName, sp.SalesYTD
037 * FROM Sales.SalesPerson AS sp
038 * INNER JOIN Person.Person AS c
039 * ON sp.BusinessEntityID = c.BusinessEntityID
040 * WHERE sp.BusinessEntityID LIKE '2%'
041 * ORDER BY sp.BusinessEntityID, c.LastName;
042 * </pre>
043 * select query in above insert statement can be fetched from {@link #getSubQuery}
044 *
045 * @see TCustomSqlStatement#cteList
046 * @see TCustomSqlStatement#targetTable
047 * @see TCustomSqlStatement#outputClause
048 * @see TCustomSqlStatement#returningClause
049 *
050 */
051public class TInsertSqlStatement extends TCustomSqlStatement {
052
053    private ArrayList<TInsertSqlStatement> multiInsertStatements;
054
055    /**
056     * Hive, from table insert..., insert ...
057     * @return
058     */
059    public ArrayList<TInsertSqlStatement> getMultiInsertStatements() {
060        if (this.multiInsertStatements == null){
061            this.multiInsertStatements = new ArrayList<>();
062        }
063        return multiInsertStatements;
064    }
065
066    private String fileFormat;
067    private String fileOptions = null;
068
069    public String getFileFormat() {
070        return fileFormat;
071    }
072
073    public String getFileOptions() {
074        return fileOptions;
075    }
076
077    private TObjectName sourceValueTable;
078
079    public TObjectName getSourceValueTable() {
080        return sourceValueTable;
081    }
082
083    private boolean insertAll = false;
084    private boolean insertFirst = false;
085
086    public void setInsertAll(boolean insertAll) {
087        this.insertAll = insertAll;
088    }
089
090    public void setInsertFirst(boolean insertFirst) {
091        this.insertFirst = insertFirst;
092    }
093
094    /**
095     * Oracle insert all
096     * @return Oracle insert all
097     */
098    public boolean isInsertAll() {
099
100        return insertAll;
101    }
102
103    /**
104     * Oracle insert first
105     * @return Oracle insert first
106     */
107    public boolean isInsertFirst() {
108        return insertFirst;
109    }
110
111    private TErrorLoggingClause errorLoggingClause;
112
113    /**
114     * Oracle error logging clause
115     * @return Oracle error logging clause
116     */
117    public TErrorLoggingClause getErrorLoggingClause() {
118        return errorLoggingClause;
119    }
120
121    /**
122     * Hive insert type
123     * @return Hive insert type
124     */
125    public EHiveInsertType getHiveInsertType() {
126        return hiveInsertType;
127    }
128
129    /**
130     * Hive directory name
131     * @return directory name
132     */
133    public TObjectName getDirectoryName() {
134        if( (directoryName == null)&&(fileOptions != null)){
135            String a[] = fileOptions.split("[,]");
136            for(String s:a){
137                if (s.trim().startsWith("\'path\'")){
138                    directoryName = TObjectName.createObjectName (this.dbvendor, EDbObjectType.directory_path, new TSourceToken(s.split("[ ]")[1]));
139                    break;
140                }
141            }
142        }
143        return directoryName;
144    }
145
146
147    private EHiveInsertType hiveInsertType = EHiveInsertType.intoUnknown;
148    private TObjectName directoryName = null;
149
150    private TPTNodeList<TInsertCondition>  insertConditions;
151    private TPTNodeList<TInsertIntoValue> insertIntoValues;
152
153    /**
154     * Oracle insert condition
155     * @return Oracle insert condition
156     */
157    public TPTNodeList<TInsertCondition> getInsertConditions() {
158        return insertConditions;
159    }
160
161    /**
162     * Oracle insert into values used after insert all/first clause
163     * @return Oracle insert into values used after insert all/first clause
164     */
165    public TPTNodeList<TInsertIntoValue> getInsertIntoValues() {
166        return insertIntoValues;
167    }
168
169    public void setInsertToken(TSourceToken insertToken) {
170        this.insertToken = insertToken;
171    }
172
173    /**
174     * INSERT keyword
175     * @return INSERT keyword
176     */
177    public TSourceToken getInsertToken() {
178
179        return insertToken;
180    }
181
182    private TSourceToken insertToken = null;
183    
184    /**
185     * value clause valid when {@link #getInsertSource} is {@link gudusoft.gsqlparser.EInsertSource#subquery}.
186     * @return {@link gudusoft.gsqlparser.stmt.TSelectSqlStatement sub-query}
187     */
188    public TSelectSqlStatement getSubQuery() {
189        return subQuery;
190    }
191
192    private TSelectSqlStatement subQuery = null;
193
194    private TFunctionCall functionCall = null;
195
196    private TMssqlExecute executeStmt = null;
197
198    /**
199     * value clause valid when {@link #getInsertSource} is {@link gudusoft.gsqlparser.EInsertSource#values_function}.
200     * @return row value was constructed by a function.
201     */
202    public TFunctionCall getFunctionCall() {
203        return functionCall;
204    }
205
206    /**
207     * Oracle PLSQL record name in values clause, {@link #getInsertSource} returns {@link  EInsertSource#values_oracle_record}
208     * @return record name in plsql.
209     */
210    public TObjectName getRecordName() {
211        return recordName;
212    }
213
214    private  TObjectName recordName = null;
215
216    /**
217     * Type of the source from where the data is coming for this insert statement.
218     * @return Type of the data source
219     */
220    public EInsertSource getInsertSource() {
221        return insertSource;
222    }
223
224    private EInsertSource insertSource = EInsertSource.values;
225
226    /**
227     * @deprecated As of v1.6.4.9, use {@link #getInsertSource} instead.
228     *
229     * @return how rows was insert into table. value can be one of
230     * <p>vt_values,  {@link #getValues}
231     * <p>vt_values_empty, syntax like: value ()
232     * <p>vt_query,   {@link #getSubQuery}
233     * <p>vt_default_values,
234     * <p>vt_execute,
235     * <p>vt_values_function, {@link #getFunctionCall} 
236     */
237    public int getValueType() {
238        return valueType;
239    }
240
241    /**
242     * value clause, valid when {@link #getInsertSource} is {@link EInsertSource#values}.
243     * represents in format like this: ((1,2,3),(4,5),(6,7,8)),
244     * if even value clause is (1,2,3), it will be saved in {@link TMultiTargetList} like ((1,2,3))
245     * <br>
246     * @return a single row value, or multi row values returned by query or value constructor.
247     */
248    public TMultiTargetList getValues() {
249        return values;
250    }
251
252    private TMultiTargetList values = null;
253
254    private int valueType = TBaseType.vt_values;
255
256    private TResultColumnList setColumnValues = null;
257
258    private TSourceToken ignore;
259    private TSourceToken priority_delayed;
260
261    private TResultColumnList onDuplicateKeyUpdate = null;
262
263    /**
264     * MySQL on duplicate key update column list.
265     * @return MySQL on duplicate key update column list
266     */
267    public TResultColumnList getOnDuplicateKeyUpdate() {
268        return onDuplicateKeyUpdate;
269    }
270
271    /**
272     * MySQL 8.0.20+ row alias for INSERT ... ON DUPLICATE KEY UPDATE.
273     * Allows referencing the inserted row values without using VALUES() function.
274     * Example: INSERT INTO t1 (a,b,c) VALUES (1,2,3) AS new ON DUPLICATE KEY UPDATE c = new.a+new.b;
275     */
276    private TObjectName insertRowAlias = null;
277
278    /**
279     * MySQL 8.0.20+ optional column aliases for the row alias.
280     * Example: INSERT INTO t1 (a,b,c) VALUES (1,2,3) AS new(m,n,p) ON DUPLICATE KEY UPDATE c = m+n;
281     */
282    private TObjectNameList insertRowAliasColumnList = null;
283
284    /**
285     * Get MySQL 8.0.20+ row alias for INSERT ... ON DUPLICATE KEY UPDATE.
286     * @return the row alias name, or null if not specified
287     */
288    public TObjectName getInsertRowAlias() {
289        return insertRowAlias;
290    }
291
292    /**
293     * Get MySQL 8.0.20+ optional column aliases for the row alias.
294     * @return the column alias list, or null if not specified
295     */
296    public TObjectNameList getInsertRowAliasColumnList() {
297        return insertRowAliasColumnList;
298    }
299
300    private TOnConflictClause onConflictClause;
301
302    /**
303     * PostgreSQL ON CONFLICT clause (UPSERT).
304     * <p>Provides access to the conflict target (columns or constraint name),
305     * the action type (DO NOTHING or DO UPDATE), and the SET/WHERE clauses
306     * for DO UPDATE actions.
307     *
308     * <p>Example:
309     * <pre>
310     * INSERT INTO tbl VALUES (1, 2) ON CONFLICT (id) DO UPDATE SET col = EXCLUDED.col;
311     * </pre>
312     *
313     * @return the ON CONFLICT clause, or null if not present
314     */
315    public TOnConflictClause getOnConflictClause() {
316        return onConflictClause;
317    }
318
319    /**
320     * IGNORE keyword used in the insert statement.
321     * @return IGNORE keyword if used, otherwise, returns null.
322     */
323    public TSourceToken getIgnore() {
324
325        return ignore;
326    }
327
328    /**
329     * DELAY, LOW_PRIORITY, HIGH_PRIORITY keyword used in insert statement.
330     * @return null if none of those keywords is used: DELAY, LOW_PRIORITY, HIGH_PRIORITY
331     */
332    public TSourceToken getPriority_delayed() {
333        return priority_delayed;
334    }
335
336    /**
337     * set column value clauses in MySQL insert statement.
338     * @return MySQL specific column value list.
339     */
340    public TResultColumnList getSetColumnValues() {
341        return setColumnValues;
342    }
343
344    public TInsertSqlStatement(EDbVendor dbvendor) {
345        super(dbvendor);
346        sqlstatementtype = ESqlStatementType.sstinsert;
347    }
348
349    void buildsql() {
350    }
351
352    void clear() {
353    }
354
355    String getasprettytext() {
356        return "";
357    }
358
359    void iterate(TVisitorAbs pvisitor) {
360    }
361
362    /**
363     * columns of the target table.
364     * @return column name list in insert into clause.
365     */
366    public TObjectNameList getColumnList() {
367        return columnList;
368    }
369
370    private TObjectNameList columnList = null;
371
372    public void setValues(TMultiTargetList values) {
373        this.values = values;
374    }
375
376    public void setColumnList(TObjectNameList columnList) {
377        this.columnList = columnList;
378    }
379
380    public void setSubQuery(TSelectSqlStatement subQuery) {
381        insertSource = EInsertSource.subquery;
382        this.subQuery = subQuery;
383    }
384
385    /**
386     * SQL Server, execute statement used in the insert statement.
387     * {@link #getInsertSource()} returns {@link EInsertSource#execute}
388     *
389     * @return SQL Server, execute statement
390     */
391    public TMssqlExecute getExecuteStmt() {
392        return executeStmt;
393    }
394
395    private TPTNodeList<TInsertIntoValue> elseIntoValues;
396
397    /**
398     * Oracle,  values in else clause
399     * @return values in else clause
400     */
401    public TPTNodeList<TInsertIntoValue> getElseIntoValues() {
402        return elseIntoValues;
403    }
404
405    public int doParseStatement(TCustomSqlStatement psql) {
406        if (rootNode == null) return -1;
407        TInsertSqlNode insertNode = (TInsertSqlNode)rootNode;
408
409        if (this.sourcetokenlist.size() == 0){
410            // subquery nested in other statements.
411            this.setStartToken(insertNode.getStartToken());
412            this.setEndToken(insertNode.getEndToken());
413        }
414
415        super.doParseStatement(psql);
416
417        if (insertNode.hasInvalidColumnList()) {
418            TSourceToken errorToken = insertNode.getInsertToken();
419            if (errorToken != null) {
420                parseerrormessagehandle(new TSyntaxError(errorToken,
421                        "invalid INSERT column list", EErrorType.sperror,
422                        TBaseType.MSG_ERROR_SYNTAX_ERROR, this));
423            } else {
424                parseerrormessagehandle(new TSyntaxError("INSERT", 0, 0,
425                        "invalid INSERT column list", EErrorType.sperror,
426                        TBaseType.MSG_ERROR_SYNTAX_ERROR, this, -1));
427            }
428            return TBaseType.MSG_ERROR_SYNTAX_ERROR;
429        }
430
431        this.insertToken = insertNode.getInsertToken();
432        this.ignore = insertNode.getIgnore();
433        this.priority_delayed = insertNode.getPriority_delayed();
434        this.insertAll = insertNode.isInsertAll();
435        this.insertFirst = insertNode.isInsertFirst();
436        this.hiveInsertType = insertNode.getHiveInsertType();
437
438        this.valueType = insertNode.getValueType();
439
440        // Databricks supports INSERT OVERWRITE [LOCAL] DIRECTORY as well (Mantis 4646)
441        if((dbvendor == EDbVendor.dbvhive)||(dbvendor == EDbVendor.dbvsparksql)||(dbvendor == EDbVendor.dbvdatabricks)){
442
443            this.hiveInsertType = insertNode.getHiveInsertType();
444            this.directoryName = insertNode.getDirectoryName();
445            this.fileFormat = insertNode.getFileFormat();
446            this.fileOptions = insertNode.getFileOptions();
447            if (insertNode.getInsertSqlNodes() != null){
448                for(int i=1;i<insertNode.getInsertSqlNodes().size();i++){
449                    // i=1, start from the second insert statement, the first is this insert statement itself.
450                    TInsertSqlStatement newInsert = new TInsertSqlStatement(this.dbvendor);
451                    newInsert.rootNode = insertNode.getInsertSqlNodes().get(i);
452                    newInsert.setFrameStack(this.getFrameStack());
453                    newInsert.doParseStatement(psql);
454                    this.getMultiInsertStatements().add(newInsert);
455                }
456            }
457        }
458
459        if (insertNode.cteList != null){
460            this.setCteList( insertNode.cteList);
461            this.getCteList().doParse(this, ESqlClause.cte);
462        }
463
464
465        if (insertNode.getTopClause() != null){
466           insertNode.getTopClause().doParse(this,ESqlClause.top);
467           this.setTopClause(insertNode.getTopClause());
468        }
469
470        if ((this.valueType != TBaseType.vt_values_multi_table)
471                &&(insertNode.getTargetTable() != null)
472            )
473        {
474           // System.out.println(insertNode.getTargetTable().toString());
475           TTable lcTable = analyzeFromTable(insertNode.getTargetTable(),true);
476           lcTable.setEffectType(ETableEffectType.tetInsert);
477           setTargetTable(lcTable);
478           this.getRelations().add(lcTable);
479        }
480
481        if (insertNode.getColumnList() != null){
482            this.columnList = insertNode.getColumnList(); 
483            TObjectName crf ;
484            for (int i=0;i< insertNode.getColumnList().size();i++){
485                crf =insertNode.getColumnList().getObjectName(i);
486                // link this column to last 2 tables
487                crf.setLocation(ESqlClause.insertColumn);
488                getTargetTable().getObjectNameReferences().addObjectName(crf);
489                getTargetTable().getLinkedColumns().addObjectName(crf);
490                crf.setSourceTable(getTargetTable());
491            }
492
493            //insertNode.getColumnList().doParse(this,TBaseType.insertColumnClause);
494        }
495
496        if (insertNode.getOutputClause() != null){
497            insertNode.getOutputClause().doParse(this,ESqlClause.output);
498            this.setOutputClause(insertNode.getOutputClause());
499        }
500
501        switch(valueType){
502            case TBaseType.vt_values:
503                insertSource = EInsertSource.values;
504                insertNode.getValues().doParse(this,ESqlClause.insertValues);
505                this.values = insertNode.getValues();
506                // check is count of value list is the same as column list
507                if (columnList != null){
508                    TMultiTarget mt;
509                    TSourceToken st1;
510                    // Hive/Impala INSERT ... (cols) PARTITION (p1, p2=v) VALUES (...):
511                    // each dynamic partition column (no '=value') is supplied by the
512                    // VALUES row, so it raises the expected value count by one.
513                    // Scoped to the Hive family, where dynamic partition columns are
514                    // part of the row; Oracle-style PARTITION (name) does not add values.
515                    int dynamicPartitionCols = 0;
516                    if ((this.dbvendor == EDbVendor.dbvimpala || this.dbvendor == EDbVendor.dbvhive
517                            || this.dbvendor == EDbVendor.dbvsparksql)
518                            && (getTargetTable() != null)
519                            && (getTargetTable().getPartitionExtensionClause() != null)
520                            && (getTargetTable().getPartitionExtensionClause().getKeyValues() != null)){
521                        TExpressionList lcPartitionVals = getTargetTable().getPartitionExtensionClause().getKeyValues();
522                        for(int k=0;k<lcPartitionVals.size();k++){
523                            if (lcPartitionVals.getExpression(k).getExpressionType() != EExpressionType.assignment_t){
524                                dynamicPartitionCols++;
525                            }
526                        }
527                    }
528                    for(int k=0;k<values.size();k++){
529                        mt = values.getMultiTarget(k);
530                        if (mt.getColumnList() == null) continue;
531                        if (mt.getColumnList().size() == 0) continue;
532                        if (mt.getColumnList().getResultColumn(0).getExpr() == null) continue;
533                        if (mt.getColumnList().getResultColumn(0).getExpr().getExpressionType() == EExpressionType.subquery_t) continue;
534                        if (mt.getColumnList().size() == columnList.size() + dynamicPartitionCols) continue;
535                        if (mt.getColumnList().size() != columnList.size()){
536                            st1 = mt.getColumnList().getStartToken();
537                            TSyntaxError err = new TSyntaxError(st1.toString()
538                                    ,st1.lineNo,st1.columnNo
539                                    ,String.format("value count(%d) is not the same as column list(%d)",mt.getColumnList().size(),columnList.size())
540                                    ,EErrorType.sperror ,TBaseType.MSG_ERROR_INSERT_VALUE_COLUMN_NUMBER_NOT_MATCH,this,st1.posinlist);
541                            this.parseerrormessagehandle( err);
542                        }
543                    }
544                }
545                break;
546            case TBaseType.vt_values_empty:
547                insertSource = EInsertSource.values_empty;
548                break;
549            case TBaseType.vt_values_multi_table:
550                insertSource = EInsertSource.values_multi_table;
551                if (subQuery == null){
552                    subQuery = new TSelectSqlStatement(this.dbvendor);
553                    subQuery.rootNode = insertNode.getSubQueryNode();
554                }
555                subQuery.doParseStatement(this);
556
557                break;
558            case TBaseType.vt_query:
559                insertSource = EInsertSource.subquery;
560                if (subQuery == null){
561                    subQuery = new TSelectSqlStatement(this.dbvendor);
562                    subQuery.rootNode = insertNode.getSubQueryNode();
563                }
564                subQuery.doParseStatement(this);
565                break;
566            case TBaseType.vt_hive_query:
567                insertSource = EInsertSource.hive_query;
568                if (subQuery == null){
569                    subQuery = new TSelectSqlStatement(this.dbvendor);
570                    subQuery.rootNode = insertNode.getSubQueryNode();
571                }
572                subQuery.doParseStatement(this);
573                break;
574            case TBaseType.vt_default_values:
575                insertSource = EInsertSource.default_values;
576                break;
577            case TBaseType.vt_execute:
578                insertSource = EInsertSource.execute;
579                executeStmt = new TMssqlExecute(EDbVendor.dbvmssql);
580                executeStmt.rootNode = insertNode.getExecuteSqlNode();
581                executeStmt.doParseStatement(this);
582                break;
583            case TBaseType.vt_values_function:
584                insertSource = EInsertSource.values_function;
585                insertNode.getFunctionCall().doParse(this,ESqlClause.insertValues);
586
587                this.functionCall = insertNode.getFunctionCall(); 
588                break;
589            case TBaseType.vt_values_oracle_record:
590                insertSource = EInsertSource.values_oracle_record;
591                insertNode.getRecordName().doParse(this,ESqlClause.insertValues);
592                this.recordName = insertNode.getRecordName();
593                break;
594            case TBaseType.vt_set_column_value:
595                insertSource = EInsertSource.set_column_value;
596                this.setColumnValues = insertNode.getSetColumnValues();
597                this.setColumnValues.doParse(this,ESqlClause.insertValues);
598                break;
599            case TBaseType.vt_table:
600                insertSource = EInsertSource.value_table;
601                this.sourceValueTable = insertNode.getSourceValueTable();
602                break;
603        }
604
605        if (insertNode.getInsertConditions() != null){
606            this.valueType = TBaseType.vt_values_multi_table;
607            this.insertConditions = insertNode.getInsertConditions();
608            this.insertConditions.doParse(this,ESqlClause.insertValues);
609            setTargetTable(insertConditions.getElement(0).getInsertIntoValues().getElement(0).getTable() );
610        }
611
612        if (insertNode.getInsertIntoValues() != null){
613            this.valueType = TBaseType.vt_values_multi_table;
614            this.insertIntoValues = insertNode.getInsertIntoValues();
615            this.insertIntoValues.doParse(this,ESqlClause.insertValues);
616            setTargetTable(insertIntoValues.getElement(0).getTable());
617        }
618
619        if (insertNode.getElseIntoValues() != null){
620            this.valueType = TBaseType.vt_values_multi_table;
621            this.elseIntoValues = insertNode.getElseIntoValues();
622            this.elseIntoValues.doParse(this,ESqlClause.insertValues);
623            setTargetTable(elseIntoValues.getElement(0).getTable());
624        }
625
626        if (insertNode.getReturningClause() != null){
627            insertNode.getReturningClause().doParse(this,ESqlClause.returning);
628            this.setReturningClause(insertNode.getReturningClause());
629        }
630
631        if (insertNode.getOnDuplicateKeyUpdate() != null){
632            this.onDuplicateKeyUpdate = insertNode.getOnDuplicateKeyUpdate();
633            onDuplicateKeyUpdate.doParse(this,ESqlClause.unknown);
634        }
635
636        // MySQL 8.0.20+ row alias for INSERT ... ON DUPLICATE KEY UPDATE
637        this.insertRowAlias = insertNode.getInsertRowAlias();
638        this.insertRowAliasColumnList = insertNode.getInsertRowAliasColumnList();
639
640        // PostgreSQL ON CONFLICT clause
641        if (insertNode.getOnConflictClause() != null){
642            this.onConflictClause = insertNode.getOnConflictClause();
643            onConflictClause.doParse(this, ESqlClause.unknown);
644        }
645
646        errorLoggingClause = insertNode.getErrorLoggingClause();
647        return 0;
648    }
649
650    public void accept(TParseTreeVisitor v){
651        v.preVisit(this);
652
653        v.postVisit(this);
654    }
655
656    public void acceptChildren(TParseTreeVisitor v){
657        v.preVisit(this);
658
659        if (this.getCteList() != null){
660            this.getCteList().acceptChildren(v);
661        }
662
663        if (this.getTopClause() != null){
664            this.getTopClause().acceptChildren(v);
665        }
666
667        if (this.getTargetTable() != null){
668            this.getTargetTable().acceptChildren(v);
669        }
670
671        if (this.getColumnList() != null){
672            this.getColumnList().acceptChildren(v);
673        }
674
675        if (this.getOutputClause() != null){
676            this.getOutputClause().acceptChildren(v);
677        }
678
679        switch(this.getValueType()){
680            case TBaseType.vt_values:
681                if (this.getValues() != null) {
682                    this.getValues().acceptChildren(v);
683                }
684                break;
685            case TBaseType.vt_values_empty:
686                break;
687            case TBaseType.vt_query:
688                if (this.getSubQuery() != null) {
689                    this.getSubQuery().acceptChildren(v);
690                }
691                break;
692            case TBaseType.vt_values_function:
693                if (this.getFunctionCall() != null) {
694                    this.getFunctionCall().acceptChildren(v);
695                }
696                break;
697            case TBaseType.vt_values_oracle_record:
698                if (this.getRecordName() != null) {
699                    this.getRecordName().acceptChildren(v);
700                }
701                break;
702            case TBaseType.vt_set_column_value:
703                if (this.getSetColumnValues() != null) {
704                    this.getSetColumnValues().acceptChildren(v);
705                }
706                break;
707            case TBaseType.vt_values_multi_table:
708                // Oracle INSERT ALL/FIRST: traverse conditional inserts, unconditional inserts, else clause, and source subquery
709                if (this.getInsertConditions() != null) {
710                    this.getInsertConditions().acceptChildren(v);
711                }
712                if (this.getInsertIntoValues() != null) {
713                    this.getInsertIntoValues().acceptChildren(v);
714                }
715                if (this.getElseIntoValues() != null) {
716                    this.getElseIntoValues().acceptChildren(v);
717                }
718                if (this.getSubQuery() != null) {
719                    this.getSubQuery().acceptChildren(v);
720                }
721                break;
722            default:
723                break;
724        }
725
726        if (this.onConflictClause != null){
727            this.onConflictClause.acceptChildren(v);
728        }
729
730        if (this.getReturningClause() != null){
731            this.getReturningClause().acceptChildren(v);
732        }
733
734        v.postVisit(this);
735    }
736
737    public void setErrorLoggingClause(TErrorLoggingClause errorLoggingClause) {
738        this.errorLoggingClause = errorLoggingClause;
739    }
740
741    public void setHiveInsertType(EHiveInsertType hiveInsertType) {
742        this.hiveInsertType = hiveInsertType;
743    }
744
745    public void setDirectoryName(TObjectName directoryName) {
746        this.directoryName = directoryName;
747    }
748
749    public void setInsertConditions(TPTNodeList<TInsertCondition> insertConditions) {
750        this.insertConditions = insertConditions;
751    }
752
753    public void setInsertIntoValues(TPTNodeList<TInsertIntoValue> insertIntoValues) {
754        this.insertIntoValues = insertIntoValues;
755    }
756
757    public void setFunctionCall(TFunctionCall functionCall) {
758        this.functionCall = functionCall;
759    }
760
761    public void setExecuteStmt(TMssqlExecute executeStmt) {
762        this.executeStmt = executeStmt;
763    }
764
765    public void setRecordName(TObjectName recordName) {
766        this.recordName = recordName;
767    }
768
769    public void setInsertSource(EInsertSource insertSource) {
770        this.insertSource = insertSource;
771    }
772
773    public void setValueType(int valueType) {
774        this.valueType = valueType;
775    }
776
777    public void setSetColumnValues(TResultColumnList setColumnValues) {
778        this.setColumnValues = setColumnValues;
779    }
780
781    public void setOnDuplicateKeyUpdate(TResultColumnList onDuplicateKeyUpdate) {
782        this.onDuplicateKeyUpdate = onDuplicateKeyUpdate;
783    }
784}