diff --git a/enginetest/queries/script_queries.go b/enginetest/queries/script_queries.go index 22d5e4f1b0..510085e225 100644 --- a/enginetest/queries/script_queries.go +++ b/enginetest/queries/script_queries.go @@ -122,6 +122,67 @@ type ScriptTestAssertion struct { // Unlike other engine tests, ScriptTests must be self-contained. No other tables are created outside the definition of // the tests. var ScriptTests = []ScriptTest{ + { + // https://github.com/dolthub/go-mysql-server/issues/3259 + Dialect: "mysql", + Name: "Missing column with same name as system variable", + SetUpScript: []string{ + "CREATE DATABASE IF NOT EXISTS test_db", + "USE test_db", + "CREATE TABLE A (id INT)", + "CREATE TABLE B (id INT)", + "INSERT INTO A VALUES (1)", + "INSERT INTO B VALUES (2)", + }, + Assertions: []ScriptTestAssertion{ + { + Query: "SELECT UNIX_TIMESTAMP(A.timestamp) FROM A LIMIT 1", + ExpectedErr: sql.ErrTableColumnNotFound, + }, + { + Query: "SELECT A.timestamp FROM A", + ExpectedErr: sql.ErrTableColumnNotFound, + }, + { + Query: "SELECT A.version FROM A", + ExpectedErr: sql.ErrTableColumnNotFound, + }, + { + Query: "SELECT A.max_connections FROM A", + ExpectedErr: sql.ErrTableColumnNotFound, + }, + { + Query: "SELECT UPPER(A.sql_mode) FROM A", + ExpectedErr: sql.ErrTableColumnNotFound, + }, + { + Query: "SELECT @@timestamp", + Expected: []sql.Row{{float64(0)}}, + SkipResultsCheck: true, // dynamic var + }, + { + Query: "SELECT @@version", + Expected: []sql.Row{{""}}, + SkipResultsCheck: true, // dynamic var + }, + { + Query: "SELECT test_db.A.timestamp FROM A", + ExpectedErr: sql.ErrTableColumnNotFound, + }, + { + Query: "SELECT test_db.A.version FROM test_db.A", + ExpectedErr: sql.ErrTableColumnNotFound, + }, + { + Query: "SELECT a1.timestamp FROM A a1 JOIN B b1 ON a1.id = b1.id", + ExpectedErr: sql.ErrTableColumnNotFound, + }, + { + Query: "SELECT b1.max_connections FROM A a1 JOIN B b1 ON a1.id = b1.id", + ExpectedErr: sql.ErrTableColumnNotFound, + }, + }, + }, { // https://github.com/dolthub/dolt/issues/9927 // https://github.com/dolthub/dolt/issues/9053 diff --git a/sql/planbuilder/scalar.go b/sql/planbuilder/scalar.go index ecf4453211..5d83706230 100644 --- a/sql/planbuilder/scalar.go +++ b/sql/planbuilder/scalar.go @@ -126,9 +126,15 @@ func (b *Builder) buildScalar(inScope *scope, e ast.Expr) (ex sql.Expression) { if aliasedExpr, ok := inScope.selectAliases[colName]; ok { return aliasedExpr } - sysVar, scope, ok := b.buildSysVar(v, ast.SetScope_None) - if ok { - return sysVar + // Only try system variable lookup if there's no table qualifier. + // Qualified names like "A.timestamp" are always column references, never system variables. + var scope ast.SetScope + if tblName == "" && dbName == "" { + var sysVar sql.Expression + sysVar, scope, ok = b.buildSysVar(v, ast.SetScope_None) + if ok { + return sysVar + } } var err error if scope == ast.SetScope_User || scope == ast.SetScope_Persist || scope == ast.SetScope_PersistOnly {