-
-
Notifications
You must be signed in to change notification settings - Fork 238
Hooks example #3303
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
base: main
Are you sure you want to change the base?
Hooks example #3303
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,110 @@ | ||
| // Copyright 2025 Dolthub, Inc. | ||
| // | ||
| // Licensed under the Apache License, Version 2.0 (the "License"); | ||
| // you may not use this file except in compliance with the License. | ||
| // You may obtain a copy of the License at | ||
| // | ||
| // http://www.apache.org/licenses/LICENSE-2.0 | ||
| // | ||
| // Unless required by applicable law or agreed to in writing, software | ||
| // distributed under the License is distributed on an "AS IS" BASIS, | ||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| // See the License for the specific language governing permissions and | ||
| // limitations under the License. | ||
|
|
||
| package hooks | ||
|
|
||
| import ( | ||
| "github.com/dolthub/go-mysql-server/sql" | ||
| "github.com/dolthub/go-mysql-server/sql/plan" | ||
| ) | ||
|
|
||
| // Global is a variable that contains the interface for calling hooks. By default, this contains no-op hooks as | ||
| // integrators may implement their own hooks. This variable should be overwritten by the integrator. | ||
| var Global Hooks | ||
|
|
||
| // Hooks is an interface that represents various hooks that are called within a statement's lifecycle. | ||
| type Hooks interface { | ||
| // Table returns hooks related to direct table statements. | ||
| Table() Table | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. All of these should probably be plural, returning either a slice of hooks or an iterator over them. We should assume that there is going to be a chain of hooks that integrators set up to run in some order they choose. |
||
| // TableColumn returns hooks related to table column statements. | ||
| TableColumn() TableColumn | ||
| } | ||
|
|
||
| // Table contains hooks related to direct table statements. | ||
| type Table interface { | ||
| // Create returns hooks related to CREATE TABLE statements. | ||
| Create() CreateTable | ||
| // Rename returns hooks related to RENAME TABLE statements. | ||
| Rename() RenameTable | ||
| // Drop returns hooks related to DROP TABLE statements. | ||
| Drop() DropTable | ||
| } | ||
|
|
||
| // TableColumn contains hooks related to table column statements. | ||
| type TableColumn interface { | ||
| // Add returns hooks related to ALTER TABLE ... ADD COLUMN statements. | ||
| Add() TableAddColumn | ||
| // Rename returns hooks related to ALTER TABLE ... RENAME COLUMN statements. | ||
| Rename() TableRenameColumn | ||
| // Modify returns hooks related to ALTER TABLE ... MODIFY COLUMN statements. | ||
| Modify() TableModifyColumn | ||
| // Drop returns hooks related to ALTER TABLE ... DROP COLUMN statements. | ||
| Drop() TableDropColumn | ||
| } | ||
|
|
||
| // CreateTable contains hooks related to CREATE TABLE statements. | ||
| type CreateTable interface { | ||
| // PreSQLExecution is called before the final step of statement execution, after analysis. | ||
| PreSQLExecution(*sql.Context, *plan.CreateTable) (*plan.CreateTable, error) | ||
| // PostSQLExecution is called after the final step of statement execution, after analysis. | ||
| PostSQLExecution(*sql.Context, *plan.CreateTable) error | ||
| } | ||
|
|
||
| // RenameTable contains hooks related to RENAME TABLE statements. | ||
| type RenameTable interface { | ||
| // PreSQLExecution is called before the final step of statement execution, after analysis. | ||
| PreSQLExecution(*sql.Context, *plan.RenameTable) (*plan.RenameTable, error) | ||
| // PostSQLExecution is called after the final step of statement execution, after analysis. | ||
| PostSQLExecution(*sql.Context, *plan.RenameTable) error | ||
| } | ||
|
|
||
| // DropTable contains hooks related to DROP TABLE statements. | ||
| type DropTable interface { | ||
| // PreSQLExecution is called before the final step of statement execution, after analysis. | ||
| PreSQLExecution(*sql.Context, *plan.DropTable) (*plan.DropTable, error) | ||
| // PostSQLExecution is called after the final step of statement execution, after analysis. | ||
| PostSQLExecution(*sql.Context, *plan.DropTable) error | ||
| } | ||
|
|
||
| // TableAddColumn contains hooks related to ALTER TABLE ... ADD COLUMN statements. | ||
| type TableAddColumn interface { | ||
| // PreSQLExecution is called before the final step of statement execution, after analysis. | ||
| PreSQLExecution(*sql.Context, *plan.AddColumn) (*plan.AddColumn, error) | ||
| // PostSQLExecution is called after the final step of statement execution, after analysis. | ||
| PostSQLExecution(*sql.Context, *plan.AddColumn) error | ||
| } | ||
|
|
||
| // TableRenameColumn contains hooks related to ALTER TABLE ... RENAME COLUMN statements. | ||
| type TableRenameColumn interface { | ||
| // PreSQLExecution is called before the final step of statement execution, after analysis. | ||
| PreSQLExecution(*sql.Context, *plan.RenameColumn) (*plan.RenameColumn, error) | ||
| // PostSQLExecution is called after the final step of statement execution, after analysis. | ||
| PostSQLExecution(*sql.Context, *plan.RenameColumn) error | ||
| } | ||
|
|
||
| // TableModifyColumn contains hooks related to ALTER TABLE ... MODIFY COLUMN statements. | ||
| type TableModifyColumn interface { | ||
| // PreSQLExecution is called before the final step of statement execution, after analysis. | ||
| PreSQLExecution(*sql.Context, *plan.ModifyColumn) (*plan.ModifyColumn, error) | ||
| // PostSQLExecution is called after the final step of statement execution, after analysis. | ||
| PostSQLExecution(*sql.Context, *plan.ModifyColumn) error | ||
| } | ||
|
|
||
| // TableDropColumn contains hooks related to ALTER TABLE ... DROP COLUMN statements. | ||
| type TableDropColumn interface { | ||
| // PreSQLExecution is called before the final step of statement execution, after analysis. | ||
| PreSQLExecution(*sql.Context, *plan.DropColumn) (*plan.DropColumn, error) | ||
| // PostSQLExecution is called after the final step of statement execution, after analysis. | ||
| PostSQLExecution(*sql.Context, *plan.DropColumn) error | ||
| } | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Probably just put this in noop.go in the same package as the defn |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,192 @@ | ||
| // Copyright 2025 Dolthub, Inc. | ||
| // | ||
| // Licensed under the Apache License, Version 2.0 (the "License"); | ||
| // you may not use this file except in compliance with the License. | ||
| // You may obtain a copy of the License at | ||
| // | ||
| // http://www.apache.org/licenses/LICENSE-2.0 | ||
| // | ||
| // Unless required by applicable law or agreed to in writing, software | ||
| // distributed under the License is distributed on an "AS IS" BASIS, | ||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| // See the License for the specific language governing permissions and | ||
| // limitations under the License. | ||
|
|
||
| package noop | ||
|
|
||
| import ( | ||
| "github.com/dolthub/go-mysql-server/sql" | ||
| "github.com/dolthub/go-mysql-server/sql/hooks" | ||
| "github.com/dolthub/go-mysql-server/sql/plan" | ||
| ) | ||
|
|
||
| // init sets the global hooks to be no-ops by default. It is intended that the variable will be replaced by the | ||
| // integrator. | ||
| func init() { | ||
| hooks.Global = NoOp{} | ||
| } | ||
|
|
||
| // NoOp implements hooks.Hooks while having all operations be no-ops. Integrators may supply their own implementation. | ||
| type NoOp struct{} | ||
|
|
||
| var _ hooks.Hooks = NoOp{} | ||
|
|
||
| // Table implements the interface hooks.Hooks. | ||
| func (NoOp) Table() hooks.Table { | ||
| return Table{} | ||
| } | ||
|
|
||
| // TableColumn implements the interface hooks.Hooks. | ||
| func (NoOp) TableColumn() hooks.TableColumn { | ||
| return TableColumn{} | ||
| } | ||
|
|
||
| // Table implements no-ops for the hooks.Table interface. | ||
| type Table struct{} | ||
|
|
||
| var _ hooks.Table = Table{} | ||
|
|
||
| // Create implements the interface hooks.Table. | ||
| func (Table) Create() hooks.CreateTable { | ||
| return CreateTable{} | ||
| } | ||
|
|
||
| // Rename implements the interface hooks.Table. | ||
| func (Table) Rename() hooks.RenameTable { | ||
| return RenameTable{} | ||
| } | ||
|
|
||
| // Drop implements the interface hooks.Table. | ||
| func (Table) Drop() hooks.DropTable { | ||
| return DropTable{} | ||
| } | ||
|
|
||
| // TableColumn implements no-ops for the hooks.TableColumn interface. | ||
| type TableColumn struct{} | ||
|
|
||
| var _ hooks.TableColumn = TableColumn{} | ||
|
|
||
| // Add implements the interface hooks.TableColumn. | ||
| func (TableColumn) Add() hooks.TableAddColumn { | ||
| return TableAddColumn{} | ||
| } | ||
|
|
||
| // Rename implements the interface hooks.TableColumn. | ||
| func (TableColumn) Rename() hooks.TableRenameColumn { | ||
| return TableRenameColumn{} | ||
| } | ||
|
|
||
| // Modify implements the interface hooks.TableColumn. | ||
| func (TableColumn) Modify() hooks.TableModifyColumn { | ||
| return TableModifyColumn{} | ||
| } | ||
|
|
||
| // Drop implements the interface hooks.TableColumn. | ||
| func (TableColumn) Drop() hooks.TableDropColumn { | ||
| return TableDropColumn{} | ||
| } | ||
|
|
||
| // CreateTable implements no-ops for the hooks.CreateTable interface. | ||
| type CreateTable struct{} | ||
|
|
||
| var _ hooks.CreateTable = CreateTable{} | ||
|
|
||
| // PreSQLExecution implements the interface hooks.CreateTable. | ||
| func (CreateTable) PreSQLExecution(_ *sql.Context, n *plan.CreateTable) (*plan.CreateTable, error) { | ||
| return n, nil | ||
| } | ||
|
|
||
| // PostSQLExecution implements the interface hooks.CreateTable. | ||
| func (CreateTable) PostSQLExecution(_ *sql.Context, n *plan.CreateTable) error { | ||
| return nil | ||
| } | ||
|
|
||
| // RenameTable implements no-ops for the hooks.RenameTable interface. | ||
| type RenameTable struct{} | ||
|
|
||
| var _ hooks.RenameTable = RenameTable{} | ||
|
|
||
| // PreSQLExecution implements the interface hooks.RenameTable. | ||
| func (RenameTable) PreSQLExecution(_ *sql.Context, n *plan.RenameTable) (*plan.RenameTable, error) { | ||
| return n, nil | ||
| } | ||
|
|
||
| // PostSQLExecution implements the interface hooks.RenameTable. | ||
| func (RenameTable) PostSQLExecution(_ *sql.Context, n *plan.RenameTable) error { | ||
| return nil | ||
| } | ||
|
|
||
| // DropTable implements no-ops for the hooks.DropTable interface. | ||
| type DropTable struct{} | ||
|
|
||
| var _ hooks.DropTable = DropTable{} | ||
|
|
||
| // PreSQLExecution implements the interface hooks.DropTable. | ||
| func (DropTable) PreSQLExecution(_ *sql.Context, n *plan.DropTable) (*plan.DropTable, error) { | ||
| return n, nil | ||
| } | ||
|
|
||
| // PostSQLExecution implements the interface hooks.DropTable. | ||
| func (DropTable) PostSQLExecution(_ *sql.Context, n *plan.DropTable) error { | ||
| return nil | ||
| } | ||
|
|
||
| // TableAddColumn implements no-ops for the hooks.TableAddColumn interface. | ||
| type TableAddColumn struct{} | ||
|
|
||
| var _ hooks.TableAddColumn = TableAddColumn{} | ||
|
|
||
| // PreSQLExecution implements the interface hooks.TableAddColumn. | ||
| func (TableAddColumn) PreSQLExecution(_ *sql.Context, n *plan.AddColumn) (*plan.AddColumn, error) { | ||
| return n, nil | ||
| } | ||
|
|
||
| // PostSQLExecution implements the interface hooks.TableAddColumn. | ||
| func (TableAddColumn) PostSQLExecution(_ *sql.Context, n *plan.AddColumn) error { | ||
| return nil | ||
| } | ||
|
|
||
| // TableRenameColumn implements no-ops for the hooks.TableRenameColumn interface. | ||
| type TableRenameColumn struct{} | ||
|
|
||
| var _ hooks.TableRenameColumn = TableRenameColumn{} | ||
|
|
||
| // PreSQLExecution implements the interface hooks.TableRenameColumn. | ||
| func (TableRenameColumn) PreSQLExecution(_ *sql.Context, n *plan.RenameColumn) (*plan.RenameColumn, error) { | ||
| return n, nil | ||
| } | ||
|
|
||
| // PostSQLExecution implements the interface hooks.TableRenameColumn. | ||
| func (TableRenameColumn) PostSQLExecution(_ *sql.Context, n *plan.RenameColumn) error { | ||
| return nil | ||
| } | ||
|
|
||
| // TableModifyColumn implements no-ops for the hooks.TableModifyColumn interface. | ||
| type TableModifyColumn struct{} | ||
|
|
||
| var _ hooks.TableModifyColumn = TableModifyColumn{} | ||
|
|
||
| // PreSQLExecution implements the interface hooks.TableModifyColumn. | ||
| func (TableModifyColumn) PreSQLExecution(_ *sql.Context, n *plan.ModifyColumn) (*plan.ModifyColumn, error) { | ||
| return n, nil | ||
| } | ||
|
|
||
| // PostSQLExecution implements the interface hooks.TableModifyColumn. | ||
| func (TableModifyColumn) PostSQLExecution(_ *sql.Context, n *plan.ModifyColumn) error { | ||
| return nil | ||
| } | ||
|
|
||
| // TableDropColumn implements no-ops for the hooks.TableDropColumn interface. | ||
| type TableDropColumn struct{} | ||
|
|
||
| var _ hooks.TableDropColumn = TableDropColumn{} | ||
|
|
||
| // PreSQLExecution implements the interface hooks.TableDropColumn. | ||
| func (TableDropColumn) PreSQLExecution(_ *sql.Context, n *plan.DropColumn) (*plan.DropColumn, error) { | ||
| return n, nil | ||
| } | ||
|
|
||
| // PostSQLExecution implements the interface hooks.TableDropColumn. | ||
| func (TableDropColumn) PostSQLExecution(_ *sql.Context, n *plan.DropColumn) error { | ||
| return nil | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rest of the interface is fine, but we should avoid having a global here if at all possible. Instead, put this on the analyzer builder, and then it can be assigned to the session for use in the exec stuff.