Repository: dolthub/dolt
File: go/libraries/doltcore/sqle/expranalysis/expranalysis.go (Go)

Code before:
func stripTableNamesFromExpression(expr sql.Expression, quoted bool) sql.Expression {
	e, _, _ := transform.Expr(expr, func(e sql.Expression) (sql.Expression, transform.TreeIdentity, error) {
		if col, ok := e.(*expression.GetField); ok {
			return col.WithTable("").WithQuotedNames(sql.GlobalSchemaFormatter, quoted), transform.NewTree, nil
		}
		return e, transform.SameTree, nil
	})
	return e
}

// Session is a way to access the Dolt session without import cycles.
type Session interface {
	GenericProvider() sql.MutableDatabaseProvider
	HasDoltgresObjects() bool
}

func parseCreateTable(ctx *sql.Context, tableName string, sch schema.Schema) (*plan.CreateTable, error) {
	createTable, err := sqlfmt.GenerateCreateTableStatement(tableName, sch, nil, nil)
	if err != nil {
		return nil, err
	}

	query := createTable

	// Dolt creates a new provider (is that necessary?), while Doltgres must use the existing provider, so we split the
	// logic here depending on whether this is Dolt or Doltgres.
	var b *planbuilder.Builder
	sess, ok := ctx.Session.(Session)
	if ok && sess.HasDoltgresObjects() {
		catalog := analyzer.NewCatalog(sess.GenericProvider())
		catalog.AuthHandler = sql.NoopAuthorizationHandler{}
		b = planbuilder.New(ctx, catalog, nil, nil)
	} else {
		mockDatabase := memory.NewDatabase("mydb")
		mockProvider := memory.NewDBProvider(mockDatabase)
		catalog := analyzer.NewCatalog(mockProvider)
		catalog.AuthHandler = sql.NoopAuthorizationHandler{}
		// We need a new context for this operation
		parseCtx := sql.NewEmptyContext()
		parseCtx.SetCurrentDatabase("mydb")

		b = planbuilder.New(parseCtx, catalog, nil, nil)
	}

	pseudoAnalyzedQuery, _, _, _, err := b.Parse(query, nil, false)
	if err != nil {
		return nil, err
	}

	ct, ok := pseudoAnalyzedQuery.(*plan.CreateTable)
	if !ok {

Review comment (suggestion):
Interesting! Creating a new provider doesn't seem like it should be necessary. Did you already try using the same code for Dolt as you added for Doltgres? If we could access the DoltDatabaseProvider and use it here, it seems like it might work. 

Code after:
func stripTableNamesFromExpression(expr sql.Expression, quoted bool) sql.Expression {
	e, _, _ := transform.Expr(expr, func(e sql.Expression) (sql.Expression, transform.TreeIdentity, error) {
		if col, ok := e.(*expression.GetField); ok {
			return col.WithTable("").WithQuotedNames(sql.GlobalSchemaFormatter, quoted), transform.NewTree, nil
		}
		return e, transform.SameTree, nil
	})
	return e
}

// SessionDbProvider is a way to access the Dolt database provider without import cycles.
type SessionDbProvider interface {
	GenericProvider() sql.MutableDatabaseProvider
}

func parseCreateTable(ctx *sql.Context, tableName string, sch schema.Schema) (*plan.CreateTable, error) {
	createTable, err := sqlfmt.GenerateCreateTableStatement(tableName, sch, nil, nil)
	if err != nil {
		return nil, err
	}

	query := createTable

	// Doltgres must use the existing provider due to custom functions, so we split the logic here depending on whether
	// this is being called from a query context (which will have a valid Dolt session) or some other context (which
	// will need to construct a new provider).
	var b *planbuilder.Builder
	sess, ok := ctx.Session.(SessionDbProvider)
	if ok {
		catalog := analyzer.NewCatalog(sess.GenericProvider())
		catalog.AuthHandler = sql.NoopAuthorizationHandler{}
		b = planbuilder.New(ctx, catalog, nil, nil)
	} else {
		mockDatabase := memory.NewDatabase("mydb")
		mockProvider := memory.NewDBProvider(mockDatabase)
		catalog := analyzer.NewCatalog(mockProvider)
		catalog.AuthHandler = sql.NoopAuthorizationHandler{}
		// We need a new context for this operation
		parseCtx := sql.NewEmptyContext()
		parseCtx.SetCurrentDatabase("mydb")

		b = planbuilder.New(parseCtx, catalog, nil, nil)
	}

	pseudoAnalyzedQuery, _, _, _, err := b.Parse(query, nil, false)
	if err != nil {
		return nil, err
	}

	ct, ok := pseudoAnalyzedQuery.(*plan.CreateTable)
	if !ok {