001package gudusoft.gsqlparser.nodes; 002 003import gudusoft.gsqlparser.*; 004import gudusoft.gsqlparser.nodes.couchbase.TObjectConstruct; 005import gudusoft.gsqlparser.nodes.couchbase.TPair; 006import gudusoft.gsqlparser.stmt.TMergeSqlStatement; 007 008 009/** 010 * insert clause in merge statement. 011 * <pre> 012 * [when not matched [and search_conditions ] then insert [(column_list)] values (value_list)] 013 * </pre> 014 * 015 * <p> call {@link #getColumnList()} to return value for (column_list) 016 * <p> call {@link #getValuelist()} to return value for (value_list) 017 * 018 * @see TMergeWhenClause 019 */ 020 021public class TMergeInsertClause extends TMergeActionClause { 022 private TExpression insertWhereClause; 023 private TObjectNameList columnList = null; 024 private TResultColumnList valuelist; 025 private TObjectName rowTypeValue; 026 027 /** 028 * plsql row type record 029 */ 030 public TObjectName getRowTypeValue() { 031 return rowTypeValue; 032 } 033 034 public TObjectNameList getColumnList() { 035 return columnList; 036 037 } 038 039 public TExpression getInsertWhereClause() { 040 return insertWhereClause; 041 } 042 043 public TResultColumnList getValuelist() { 044 return valuelist; 045 } 046 047 public void init(Object arg1) { 048 this.mergeActionType = EMergeActionType.insert; 049 insertValue = (TExpression)arg1; 050 } 051 052 public void init(Object arg1,Object arg2){ 053 init(arg1); 054 insertWhereClause = (TExpression)arg2; 055 } 056 057 public void init(Object arg1,Object arg2,Object arg3){ 058 // Teradata BNF rule in order to avoid conflicts, the column list is replaced by target list, we need to change it back to column list 059 if (arg1 != null){ 060 if (arg1 instanceof TResultColumnList){ 061 this.columnList = new TObjectNameList(); 062 for(int i=0;i<((TResultColumnList)arg1).size();i++){ 063 TResultColumn rc = ((TResultColumnList)arg1).getResultColumn(i); 064 this.columnList.addObjectName(rc.getExpr().getObjectOperand()); 065 } 066 }else{ 067 this.columnList = (TObjectNameList)arg1; 068 } 069 } 070 071 072 if (arg2 instanceof TResultColumnList){ 073 this.valuelist = (TResultColumnList)arg2; 074 for(int i=0;i<valuelist.size();i++){ 075 TResultColumn resultColumn = valuelist.getResultColumn(i); 076 if (resultColumn.getExpr() != null){ 077 TExpression expression = resultColumn.getExpr(); 078 if ((expression.getExpressionType() == EExpressionType.simple_comparison_t)&&(expression.getComparisonOperator().tokencode == '=')){ 079 expression.setExpressionType(EExpressionType.assignment_t); 080 } 081 } 082 } 083 } 084 else if (arg2 instanceof TObjectName) 085 rowTypeValue = (TObjectName)arg2; 086 else if (arg2 instanceof TObjectNameList) { 087 // change to resultcolumnlist 088 valuelist = new TResultColumnList(); 089 TObjectNameList onList = (TObjectNameList)arg2; 090 for(int i=0;i<onList.size();i++){ 091 TResultColumn rc = new TResultColumn(); 092 TExpression retval = new TExpression(); 093 retval.init(EExpressionType.simple_object_name_t); 094 TObjectName objectName = onList.getObjectName(i); 095 objectName.setObjectType(TObjectName.ttobjColumn); 096 retval.setObjectOperand(objectName); 097 retval.setStartToken(objectName); 098 retval.setEndToken(objectName); 099 rc.init(retval); 100 valuelist.addResultColumn(rc); 101 } 102 } 103 104 if (arg3 != null){ 105 this.insertWhereClause = (TExpression)arg3; 106 } 107 } 108 109 public void doParse(TCustomSqlStatement psql, ESqlClause plocation){ 110 111 if (this.columnList != null){ 112 113 TObjectName crf ; 114 for (int i=0;i< this.columnList.size();i++){ 115 crf =this.columnList.getObjectName(i); 116 // link this column to the first tables 117 crf.setLocation(ESqlClause.insertColumn); 118 psql.getTargetTable().getObjectNameReferences().addObjectName(crf); 119 psql.getTargetTable().getLinkedColumns().addObjectName(crf); 120 crf.setSourceTable(psql.getTargetTable()); 121 crf.setValidate_column_status(TBaseType.COLUMN_LINKED_TO_TABLE_IN_OLD_ALGORITHM); 122 } 123 } 124 125 if (this.valuelist != null){ 126 for(int i=0;i<valuelist.size();i++){ 127 TResultColumn resultColumn = valuelist.getResultColumn(i); 128 if (resultColumn.getExpr() != null){ 129 TExpression expression = resultColumn.getExpr(); 130 if (expression.getObjectOperand() != null){ 131 expression.getObjectOperand().setResolveStatus(TBaseType.RESOLVE_DELAY_TO_COLUMN_RESOLVER); 132 // INSERT (id, name, joining_date) VALUES (id, TRIM(name), joining_date); 133 // 上面 values clause 中的 column 关联到 using table 的逻辑放到 TAttributeResolver 中去实现 134 // 除了关联 column 外,还可以实现 column push down 到 * column 及对应的 table 135 // 增加了下面两个方法 136 // public void preVisit(TMergeInsertClause node) 137 // public void postVisit(TMergeInsertClause node) 138 139// TMergeSqlStatement mergeSqlStatement = (TMergeSqlStatement)psql; 140// mergeSqlStatement.getUsingTable().getLinkedColumns().addObjectName(expression.getObjectOperand()); 141// expression.getObjectOperand().setSourceTable(mergeSqlStatement.getUsingTable()); 142// expression.getObjectOperand().setValidate_column_status(TBaseType.COLUMN_LINKED_TO_TABLE_IN_OLD_ALGORITHM); 143 } 144 } 145 } 146 this.valuelist.doParse(psql,ESqlClause.insertValues); 147 } 148 149 if (this.insertValue != null){ 150 if (this.insertValue.getExpressionType() == EExpressionType.objectConstruct_t){ 151 // couchbase { "name": b.name, "title": b.title, "depts": b.depts, "empId": b.empId, "dob": b.dob } 152 TObjectConstruct objectConstruct = this.insertValue.getObjectConstruct(); 153 TMergeSqlStatement mergeSqlStatement = (TMergeSqlStatement)psql; 154 for(int i=0;i<objectConstruct.getPairs().size();i++){ 155 TPair pair = objectConstruct.getPairs().getElement(i); 156 if (pair.getKeyName() != null){ 157 if (pair.getKeyName().getExpressionType() == EExpressionType.simple_constant_t){ 158 TObjectName columnName = new TObjectName(); 159 TSourceToken newSt = new TSourceToken(pair.getKeyName().getConstantOperand().getValueToken().getTextWithoutQuoted()); 160 columnName.setPartToken(newSt); 161 mergeSqlStatement.getTargetTable().getLinkedColumns().addObjectName(columnName); 162 columnName.setSourceTable(mergeSqlStatement.getTargetTable()); 163 columnName.setValidate_column_status(TBaseType.COLUMN_LINKED_TO_TABLE_IN_OLD_ALGORITHM); 164 } 165 } 166 pair.getKeyValue().doParse(psql,plocation); 167 } 168 } 169 } 170 171 if (this.insertWhereClause != null){ 172 this.insertWhereClause.doParse(psql,ESqlClause.where); 173 } 174 175 } 176 177 public void accept(TParseTreeVisitor v){ 178 v.preVisit(this); 179 v.postVisit(this); 180 } 181 182 public void acceptChildren(TParseTreeVisitor v){ 183 v.preVisit(this); 184 if (this.columnList != null){ 185 columnList.acceptChildren(v); 186 } 187 188 if (this.valuelist != null){ 189 this.valuelist.acceptChildren(v); 190 } 191 192 if (this.insertWhereClause != null){ 193 this.insertWhereClause.acceptChildren(v); 194 } 195 v.postVisit(this); 196 } 197 198 public void setInsertWhereClause(TExpression insertWhereClause) { 199 this.insertWhereClause = insertWhereClause; 200 } 201 202 public void setColumnList(TObjectNameList columnList) { 203 this.columnList = columnList; 204 } 205 206 public void setValuelist(TResultColumnList valuelist) { 207 this.valuelist = valuelist; 208 } 209 210 public void setRowTypeValue(TObjectName rowTypeValue) { 211 this.rowTypeValue = rowTypeValue; 212 } 213 214 private TExpression insertValue; //couchbase 215 216 public TExpression getInsertValue() { 217 return insertValue; 218 } 219}