Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sql: partial predicate causes error for UPDATE .. FROM #61284

Closed
RaduBerinde opened this issue Mar 1, 2021 · 7 comments · Fixed by #61522
Closed

sql: partial predicate causes error for UPDATE .. FROM #61284

RaduBerinde opened this issue Mar 1, 2021 · 7 comments · Fixed by #61522
Assignees
Labels
C-bug Code not up to spec/doc, specs & docs deemed correct. Solution expected to change code/behavior.

Comments

@RaduBerinde
Copy link
Member

A partial index predicate is generating an ambigous column error with UPDATE .. FROM, when the same column name is produced by the FROM relation. Example:

> create table t (a int primary key, b int, c int, index (b,c) where c > 0);
> update t set b=v.b, c=v.c from (values (1,1), (2,2)) as v(b,c) where t.b=v.b;
ERROR: column reference "c" is ambiguous (candidates: t.c, v.c)
SQLSTATE: 42702

The same statement works if where c > 0 is removed from the index.

@RaduBerinde RaduBerinde added the C-bug Code not up to spec/doc, specs & docs deemed correct. Solution expected to change code/behavior. label Mar 1, 2021
@RaduBerinde
Copy link
Member Author

The problem is the scope we are using to resolve partial index predicates.

In general, I believe things would be more robust if we'd build predicates once for the TableMeta and then remap the column IDs in that expression (with CopyAndReplace) according to strict column ID mappings (instead of relying on scope resolution by name). That would be a non-trivial project though (and probably not backportable).

@RaduBerinde
Copy link
Member Author

Actually, it looks like the problem is when resolving the "del" columns. We are aliasing mb.outScope with mb.fetchScope and the latter ends up containing the FROM columns.

@RaduBerinde
Copy link
Member Author

index 109e84646d..0bd2b5b662 100644
--- a/pkg/sql/opt/optbuilder/mutation_builder.go
+++ b/pkg/sql/opt/optbuilder/mutation_builder.go
@@ -287,10 +287,9 @@ func (mb *mutationBuilder) buildInputForUpdate(
 		noRowLocking,
 		inScope,
 	)
-	mb.outScope = mb.fetchScope
 
 	// Set list of columns that will be fetched by the input expression.
-	mb.setFetchColIDs(mb.outScope.cols)
+	mb.setFetchColIDs(mb.fetchScope.cols)
 
 	// If there is a FROM clause present, we must join all the tables
 	// together with the table being updated.
@@ -299,18 +298,24 @@ func (mb *mutationBuilder) buildInputForUpdate(
 		fromScope := mb.b.buildFromTables(from, noRowLocking, inScope)
 
 		// Check that the same table name is not used multiple times.
-		mb.b.validateJoinTableNames(mb.outScope, fromScope)
+		mb.b.validateJoinTableNames(mb.fetchScope, fromScope)
 
 		// The FROM table columns can be accessed by the RETURNING clause of the
 		// query and so we have to make them accessible.
 		mb.extraAccessibleCols = fromScope.cols
 
 		// Add the columns in the FROM scope.
+		// Note: we don't want to modify fetchScope here - it will be used later
+		// with partial index predicates and the FROM columns can cause ambiguities.
+		mb.outScope = mb.fetchScope.replace()
+		mb.outScope.appendColumnsFromScope(mb.fetchScope)
 		mb.outScope.appendColumnsFromScope(fromScope)
 
-		left := mb.outScope.expr.(memo.RelExpr)
+		left := mb.fetchScope.expr.(memo.RelExpr)
 		right := fromScope.expr.(memo.RelExpr)
 		mb.outScope.expr = mb.b.factory.ConstructInnerJoin(left, right, memo.TrueFilter, memo.EmptyJoinPrivate)
+	} else {
+		mb.outScope = mb.fetchScope
 	}

This fixes this particular case.

However, the "workaround attempt" in the support issue still doesn't work. That one has a problem when resolving with the PUT scope. The problem there seems to be that the "round decimal values" code interacts badly with the code that renames the "new" columns in addUpdateCols. Because the updateColIds[] map is changed by roundDecimalValues and the new column does not have the expected name.

@RaduBerinde
Copy link
Member Author

This second problem seems to be fixed by this:

 		mb.roundedDecimalCols.Add(scopeCol.id)
+		scopeCol.name = mb.tab.Column(i).ColName()

However, this all still feels very fragile; I filed separate PR #61298 to investigate a better mechanism. In the meantime, we'll need to fix in 20.2 and add tests with UPDATE .. FROM and partial indexes.

@awoods187
Copy link
Contributor

Nice analysis!

@mgartner
Copy link
Collaborator

mgartner commented Mar 2, 2021

Thanks for hunting this down @RaduBerinde! I'll work on a fixing this today.

@mgartner
Copy link
Collaborator

mgartner commented Mar 5, 2021

The "second problem" is also present with check constraints, not just partial indexes. It's a harder problem to solve, so I've opened #61520 to track it. I'm experimenting with some potential fixes.

mgartner added a commit to mgartner/cockroach that referenced this issue Mar 5, 2021
Previously, the fetch scope incorrectly included columns in the FROM
clause of an UPDATE..FROM statement. As a result, column names shared by
the FROM clause and the mutating table lead to ambiguity when resolving
partial index DEL column expressions. This commit ensures that the fetch
scope does not include columns in the FROM clause.

Fixes cockroachdb#61284

Release justification: This is a low-risk bug fix to existing
functionality.

Release note (bug fix): An UPDATE..FROM statement where the FROM clause
contained column names that match table column names erred if the table
had a partial index predicate referencing those columns. This bug,
present since partial indexes were released in version 20.2.0, has been
fixed.
craig bot pushed a commit that referenced this issue Mar 5, 2021
61359: tracing: use byte-limits for logs/structured events per span r=irfansharif a=irfansharif

Touches #59188. Follow-on work from #60678. We can introduce byte-limits for
verbose logging and structured events, instead of limiting things based on
count.

This PR also:
- adds a _dropped tag to recordings with dropped logs/structured events.
- squashes a bug where reset spans (as used in SessionTracing) still
  held onto earlier structured events
- moves away from the internal usage of the opentracing.LogRecord type,
  it's unnecessary

Release justification: low risk, high benefit changes to existing
functionality

Release note: None

---

+cc @knz / @erikgrinaker / @angelapwen for pod-visibility.

61482: jobs: add job metrics per-type to track success, failure, and cancel r=fqazi a=fqazi

Fixes: #59711

Previously, there were only over all counters tracking how many
jobs were completed, cancelled, or failed. This was inadequate
because it didn't make it easy to tell in aggregate what job
types they were. To address this, this patch will add counters
for different job types for tracking success, failure, and
cancellation.

Release justification: Low risk change only adding a metric inside
the crdb_internal.feature_usage table
Release note: None

61491: sqlsmith: add support for computed columns r=RaduBerinde a=RaduBerinde

This changes the random table generator to also create computed
columns (either STORED or VIRTUAL). Some example of definitions:
 - `col1_14 STRING NOT NULL AS (lower(CAST(col1_8 AS STRING))) VIRTUAL`
 - `col2_6 DECIMAL NOT NULL AS (col2_2 + 1:::DECIMAL) STORED`
 - `col1_13 INT4 AS (col1_0 + col1_10) STORED`

Release justification: non-production code change.

Release note: None

Informs #57608.

61509: sql: add a regression test r=RaduBerinde a=RaduBerinde

This commit adds a regression test for #58104 (the problem was already
fixed).

Resolves #58104.

Release justification: non-production code change.

Release note: None

61522: opt: fix fetch scope in UPDATE..FROM statements r=mgartner a=mgartner

Previously, the fetch scope incorrectly included columns in the FROM
clause of an UPDATE..FROM statement. As a result, column names shared by
the FROM clause and the mutating table lead to ambiguity when resolving
partial index DEL column expressions. This commit ensures that the fetch
scope does not include columns in the FROM clause.

Fixes #61284

Release justification: This is a low-risk bug fix to existing
functionality.

Release note (bug fix): An UPDATE..FROM statement where the FROM clause
contained column names that match table column names erred if the table
had a partial index predicate referencing those columns. This bug,
present since partial indexes were released in version 20.2.0, has been
fixed.

61553: ccl,server: error.Wrap on previously handled errors r=[dt,miretskiy] a=stevendanna

These errors.Wrap calls are wrapping errors that are nil and thus will
always return a nil error.

Release justification: Minor error handling fixes
Release note: None

Co-authored-by: irfan sharif <[email protected]>
Co-authored-by: Faizan Qazi <[email protected]>
Co-authored-by: Radu Berinde <[email protected]>
Co-authored-by: Marcus Gartner <[email protected]>
Co-authored-by: Steven Danna <[email protected]>
@craig craig bot closed this as completed in 99a11f7 Mar 5, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Code not up to spec/doc, specs & docs deemed correct. Solution expected to change code/behavior.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants