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}