001package gudusoft.gsqlparser.stmt.mssql; 002 003import gudusoft.gsqlparser.*; 004import gudusoft.gsqlparser.nodes.TConstant; 005import gudusoft.gsqlparser.nodes.TObjectName; 006import gudusoft.gsqlparser.nodes.TParseTreeVisitor; 007import gudusoft.gsqlparser.nodes.TTable; 008import gudusoft.gsqlparser.nodes.mssql.TMssqlUpdateTextSqlNode; 009 010/** 011 * SQL Server UPDATETEXT statement: 012 * <pre> 013 * UPDATETEXT { table.dest_column dest_text_ptr } 014 * { NULL | insert_offset } { NULL | delete_length } [ WITH LOG ] 015 * [ inserted_data | { table.src_column src_text_ptr } ] 016 * </pre> 017 * The destination (and, in the column-copy form, source) {@code table.column} 018 * reference is registered as a statement table so name resolution links the 019 * column to its table ({@link TObjectName#getSourceTable()}). 020 */ 021public class TMssqlUpdateText extends TCustomSqlStatement { 022 public TMssqlUpdateText (EDbVendor dbvendor){ 023 super(dbvendor); 024 sqlstatementtype = ESqlStatementType.sstmssqlupdatetext ; 025 } 026 027 void buildsql() { 028 } 029 030 void clear() { 031 } 032 033 String getasprettytext() { 034 return ""; 035 } 036 037 void iterate(TVisitorAbs pvisitor) { 038 } 039 040 private TObjectName destColumnName = null; 041 042 /** 043 * Is the name of the table and text, ntext, or image column to be updated. 044 * @return 045 */ 046 public TObjectName getDestColumnName() { 047 return destColumnName; 048 } 049 050 /** 051 * Is a text pointer value (returned by the TEXTPTR function) that points to the text, ntext, or image data to be updated. 052 * @return 053 */ 054 public TObjectName getDestTextPtr() { 055 return destTextPtr; 056 } 057 058 private TObjectName destTextPtr = null; 059 private TObjectName insertedVariable = null; 060 private TConstant insertedLiteral = null; 061 private TObjectName sourceColumnName = null; 062 private TObjectName sourceTextPtr = null; 063 private TTable copySourceTable = null; 064 065 /** The inserted_data operand when given as a variable, null otherwise. */ 066 public TObjectName getInsertedVariable() { 067 return insertedVariable; 068 } 069 070 /** The inserted_data operand when given as a literal, null otherwise. */ 071 public TConstant getInsertedLiteral() { 072 return insertedLiteral; 073 } 074 075 /** The source {@code table.column} of the column-copy form, null otherwise. */ 076 public TObjectName getSourceColumnName() { 077 return sourceColumnName; 078 } 079 080 /** The source text pointer of the column-copy form, null otherwise. */ 081 public TObjectName getSourceTextPtr() { 082 return sourceTextPtr; 083 } 084 085 /** The table read by the column-copy form, derived from the source column prefix. Null otherwise. */ 086 public TTable getCopySourceTable() { 087 return copySourceTable; 088 } 089 090 /** 091 * Register the table part of a fused {@code table.column} reference as a 092 * statement table and link the column to it, so both the legacy 093 * link-column phase and TSQLResolver2 consumers observe a resolved column. 094 * Returns null when the reference has no table prefix (nothing provable). 095 */ 096 static TTable bindLobColumnTable(TCustomSqlStatement stmt, TObjectName columnRef, ETableEffectType effectType) { 097 if (columnRef == null) { 098 return null; 099 } 100 columnRef.setDbObjectType(EDbObjectType.column); 101 if (columnRef.getObjectToken() == null) { 102 return null; 103 } 104 TObjectName tableName; 105 if (columnRef.getDatabaseToken() != null && columnRef.getSchemaToken() != null) { 106 tableName = TObjectName.createObjectName(stmt.dbvendor, EDbObjectType.table, 107 columnRef.getDatabaseToken(), columnRef.getSchemaToken(), columnRef.getObjectToken()); 108 } else if (columnRef.getSchemaToken() != null) { 109 tableName = TObjectName.createObjectName(stmt.dbvendor, EDbObjectType.table, 110 columnRef.getSchemaToken(), columnRef.getObjectToken()); 111 } else { 112 tableName = TObjectName.createObjectName(stmt.dbvendor, EDbObjectType.table, 113 columnRef.getObjectToken()); 114 } 115 TTable table = new TTable(tableName); 116 table.setPropertyFromObjectName(tableName, effectType); 117 table.getLinkedColumns().addObjectName(columnRef); 118 columnRef.setSourceTable(table); 119 stmt.addToTables(table); 120 return table; 121 } 122 123 public int doParseStatement(TCustomSqlStatement psql) { 124 if (rootNode == null) return -1; 125 if (!(rootNode instanceof TMssqlUpdateTextSqlNode)) { 126 // shared-dialect grammars (access/odbc) may still produce a stub or 127 // dummy node for this statement type -- degrade gracefully 128 return super.doParseStatement(psql); 129 } 130 TMssqlUpdateTextSqlNode updateTextSqlNode = (TMssqlUpdateTextSqlNode)rootNode; 131 super.doParseStatement(psql); 132 this.destColumnName = updateTextSqlNode.getDestColumnName(); 133 this.destTextPtr = updateTextSqlNode.getDestTextPtr(); 134 this.insertedVariable = updateTextSqlNode.getInsertedVariable(); 135 this.insertedLiteral = updateTextSqlNode.getInsertedLiteral(); 136 this.sourceColumnName = updateTextSqlNode.getSourceColumnName(); 137 this.sourceTextPtr = updateTextSqlNode.getSourceTextPtr(); 138 TTable table = bindLobColumnTable(this, this.destColumnName, ETableEffectType.tetUpdate); 139 if (table != null) { 140 setTargetTable(table); 141 } 142 if (this.sourceColumnName != null) { 143 this.copySourceTable = bindLobColumnTable(this, this.sourceColumnName, ETableEffectType.tetSelect); 144 } 145 return 0; 146 } 147 148 public void accept(TParseTreeVisitor v){ 149 v.preVisit(this); 150 v.postVisit(this); 151 } 152 153 public void acceptChildren(TParseTreeVisitor v){ 154 v.preVisit(this); 155 v.postVisit(this); 156 } 157 158 public void setDestColumnName(TObjectName destColumnName) { 159 this.destColumnName = destColumnName; 160 } 161 162 public void setDestTextPtr(TObjectName destTextPtr) { 163 this.destTextPtr = destTextPtr; 164 } 165}