Skip to content

TUpdateSqlStatement

Overview

The TUpdateSqlStatement node represents UPDATE statements in SQL. It handles table updates with SET clauses, WHERE conditions, and optional FROM clauses for multi-table updates.

SQL to AST Mapping

Simple UPDATE

1
2
3
UPDATE employees 
SET salary = salary * 1.1, last_updated = GETDATE()
WHERE department = 'Engineering';

AST Structure:

1
2
3
4
5
6
TUpdateSqlStatement
├── targetTable: TTable (employees)
├── resultColumnList: TResultColumnList (SET clause)
│   ├── TResultColumn (salary = salary * 1.1)
│   └── TResultColumn (last_updated = GETDATE())
└── whereClause: TWhereClause (department = 'Engineering')

UPDATE with FROM clause (SQL Server)

1
2
3
4
UPDATE dbo.Table2
SET dbo.Table2.ColB = dbo.Table2.ColB + dbo.Table1.ColB
FROM dbo.Table2
INNER JOIN dbo.Table1 ON (dbo.Table2.ColA = dbo.Table1.ColA);

AST Structure:

1
2
3
4
5
6
7
TUpdateSqlStatement
├── targetTable: TTable (dbo.Table2)
├── resultColumnList: TResultColumnList (SET clause)
│   └── TResultColumn (dbo.Table2.ColB = dbo.Table2.ColB + dbo.Table1.ColB)
└── joins: TJoinList
    ├── TJoin (dbo.Table2)
    └── TJoin (INNER JOIN dbo.Table1 ON ...)

UPDATE with subquery

1
2
3
UPDATE products 
SET price = (SELECT AVG(price) FROM products WHERE category = p.category)
WHERE product_id = 123;

AST Structure:

1
2
3
4
5
6
7
TUpdateSqlStatement
├── targetTable: TTable (products)
├── resultColumnList: TResultColumnList
│   └── TResultColumn (price = subquery)
│       └── expr: TExpression (subquery_t)
│           └── subQuery: TSelectSqlStatement
└── whereClause: TWhereClause (product_id = 123)

Key Properties

Property Type Description Access Method
targetTable TTable Target table for update getTargetTable()
resultColumnList TResultColumnList SET clause assignments getResultColumnList()
whereClause TWhereClause Filter conditions getWhereClause()
joins TJoinList FROM clause tables getJoins()
updateToken TSourceToken UPDATE keyword getUpdateToken()
topClause TTopClause TOP clause (SQL Server) getTopClause()
outputClause TOutputClause OUTPUT clause (SQL Server) getOutputClause()

Common Usage Patterns

Analyzing UPDATE Assignments

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public void analyzeUpdateStatement(TUpdateSqlStatement update) {
    System.out.println("Target table: " + update.getTargetTable().getFullName());

    // Analyze SET clause
    TResultColumnList setClause = update.getResultColumnList();
    if (setClause != null) {
        System.out.println("SET assignments:");
        for (int i = 0; i < setClause.size(); i++) {
            TResultColumn assignment = setClause.getResultColumn(i);
            TExpression expr = assignment.getExpr();

            // Get column being updated
            String columnName = getColumnName(assignment);
            System.out.println("  " + columnName + " = " + expr.toString());
        }
    }

    // Check WHERE clause
    if (update.getWhereClause() != null) {
        System.out.println("WHERE condition: " + 
            update.getWhereClause().getCondition().toString());
    } else {
        System.out.println("WARNING: No WHERE clause - affects all rows!");
    }
}

Extracting Updated Columns

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public Set<String> getUpdatedColumns(TUpdateSqlStatement update) {
    Set<String> columns = new HashSet<>();

    TResultColumnList setClause = update.getResultColumnList();
    if (setClause != null) {
        for (int i = 0; i < setClause.size(); i++) {
            TResultColumn assignment = setClause.getResultColumn(i);

            // Extract column name from assignment
            if (assignment.getAliasClause() != null) {
                columns.add(assignment.getAliasClause().toString());
            } else {
                // Parse from expression if no explicit alias
                String columnName = extractColumnFromAssignment(assignment.getExpr());
                if (columnName != null) {
                    columns.add(columnName);
                }
            }
        }
    }

    return columns;
}

Multi-table Update Analysis

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public void analyzeMultiTableUpdate(TUpdateSqlStatement update) {
    // Check if this is a multi-table update
    if (update.getJoins().size() > 0) {
        System.out.println("Multi-table update detected");

        // Target table
        System.out.println("Target: " + update.getTargetTable().getFullName());

        // Additional tables in FROM clause
        System.out.println("Additional tables:");
        for (int i = 0; i < update.getJoins().size(); i++) {
            TJoin join = update.getJoins().getJoin(i);
            TTable table = join.getTable();
            if (table != null) {
                System.out.println("  " + table.getFullName());

                // Analyze join conditions
                if (join.getJoinItems() != null) {
                    for (int j = 0; j < join.getJoinItems().size(); j++) {
                        TJoinItem joinItem = join.getJoinItems().getJoinItem(j);
                        if (joinItem.getOnCondition() != null) {
                            System.out.println("    ON: " + 
                                joinItem.getOnCondition().toString());
                        }
                    }
                }
            }
        }
    }
}

Dependency Analysis

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public Map<String, Set<String>> analyzeUpdateDependencies(TUpdateSqlStatement update) {
    Map<String, Set<String>> dependencies = new HashMap<>();

    TResultColumnList setClause = update.getResultColumnList();
    if (setClause != null) {
        for (int i = 0; i < setClause.size(); i++) {
            TResultColumn assignment = setClause.getResultColumn(i);
            TExpression expr = assignment.getExpr();

            String targetColumn = getColumnName(assignment);
            Set<String> referencedColumns = findReferencedColumns(expr);

            dependencies.put(targetColumn, referencedColumns);
        }
    }

    return dependencies;
}

private Set<String> findReferencedColumns(TExpression expr) {
    Set<String> columns = new HashSet<>();

    expr.postOrderTraverse(new IExpressionVisitor() {
        public boolean exprVisit(TParseTreeNode node, boolean isLeafNode) {
            if (node instanceof TExpression) {
                TExpression e = (TExpression) node;
                if (e.getExpressionType() == EExpressionType.simple_object_name_t) {
                    columns.add(e.getObjectOperand().toString());
                }
            }
            return true;
        }
    });

    return columns;
}

Database-Specific Features

SQL Server

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
-- TOP clause
UPDATE TOP (10) employees 
SET salary = salary * 1.1;

-- OUTPUT clause
UPDATE employees 
SET salary = salary * 1.1
OUTPUT DELETED.salary, INSERTED.salary
WHERE department = 'Sales';

-- FROM clause with joins
UPDATE e
SET salary = salary * 1.1
FROM employees e
JOIN departments d ON e.dept_id = d.id
WHERE d.name = 'Engineering';

Access via: - getTopClause() - TOP clause - getOutputClause() - OUTPUT clause - getJoins() - FROM clause tables

MySQL

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
-- Multi-table UPDATE
UPDATE employees e, departments d
SET e.salary = e.salary * 1.1
WHERE e.dept_id = d.id AND d.name = 'Engineering';

-- LIMIT clause
UPDATE employees 
SET salary = salary * 1.1 
WHERE department = 'Sales'
LIMIT 10;

-- ORDER BY with LIMIT
UPDATE employees 
SET salary = salary * 1.1 
WHERE department = 'Sales'
ORDER BY hire_date
LIMIT 10;

Access via: - getLimitClause() - LIMIT clause - getOrderByClause() - ORDER BY clause

PostgreSQL

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
-- FROM clause
UPDATE employees 
SET salary = salary * d.multiplier
FROM departments d
WHERE employees.dept_id = d.id;

-- RETURNING clause
UPDATE employees 
SET salary = salary * 1.1
WHERE department = 'Engineering'
RETURNING id, name, salary;

Access via: - getJoins() - FROM clause tables - getReturningClause() - RETURNING clause

Oracle

1
2
3
4
5
-- Error logging
UPDATE employees 
SET salary = salary * 1.1
WHERE department = 'Engineering'
LOG ERRORS INTO error_table;

Access via: - getErrorLoggingClause() - Error logging clause

Couchbase

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
-- USE KEYS/USE INDEX
UPDATE users 
USE KEYS "user123"
SET status = 'active';

-- UNSET clause
UPDATE users 
SET name = 'John'
UNSET temp_field
WHERE id = 123;

Access via: - getUseKeyIndex() - USE KEYS/INDEX clause - getUnSetTerms() - UNSET clause

Performance Considerations

Update Impact Analysis

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public void analyzeUpdateImpact(TUpdateSqlStatement update) {
    // Check for WHERE clause
    if (update.getWhereClause() == null) {
        System.out.println("WARNING: Full table update - no WHERE clause");
    }

    // Analyze updated columns for index impact
    Set<String> updatedColumns = getUpdatedColumns(update);
    System.out.println("Updated columns: " + updatedColumns);

    // Check for complex expressions in SET clause
    TResultColumnList setClause = update.getResultColumnList();
    if (setClause != null) {
        for (int i = 0; i < setClause.size(); i++) {
            TResultColumn assignment = setClause.getResultColumn(i);
            int complexity = calculateExpressionComplexity(assignment.getExpr());
            if (complexity > 5) {
                System.out.println("Complex assignment detected: " + 
                    assignment.getExpr().toString());
            }
        }
    }
}

Join Optimization Analysis

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
public void analyzeJoinPerformance(TUpdateSqlStatement update) {
    if (update.getJoins().size() > 0) {
        System.out.println("Multi-table update performance considerations:");

        // Check for proper join conditions
        for (int i = 0; i < update.getJoins().size(); i++) {
            TJoin join = update.getJoins().getJoin(i);
            if (join.getJoinItems() == null || join.getJoinItems().size() == 0) {
                System.out.println("WARNING: Cartesian product detected");
            }
        }

        // Suggest index usage
        analyzeIndexUsage(update);
    }
}

See Also