|
| 1 | +# Architecture overview |
| 2 | + |
| 3 | +This document provides an overview of all parts and pieces of the project as well as how they fit together. It is meant to help new contributors understand where things may be, and how changes in some components may interact with other components of the system. |
| 4 | + |
| 5 | +## Root package (`sqle`) |
| 6 | + |
| 7 | +This is where the engine lives. The engine is the piece that coordinates and makes all other pieces work together as well as the main API users of the system will use to create and configure an engine and perform queries. |
| 8 | + |
| 9 | +Because this is the point where all components fit together, it is also where integration tests are. Those integration tests can be found in `engine_test.go`. |
| 10 | +A test should be added here, plus in any specific place where the feature/issue belonged, if needed. |
| 11 | + |
| 12 | +**How to add integration tests** |
| 13 | + |
| 14 | +The test executing all integration test is `TestQueries`, which you can run with the following command: |
| 15 | + |
| 16 | +``` |
| 17 | +go test -run=TestQueries |
| 18 | +``` |
| 19 | + |
| 20 | +This test is just executing all the queries in a loop. New test cases should be added to the `queries` package variable at the top of `engine_test.go`. |
| 21 | +Simply add a new element to the slice with the query and the expected result. |
| 22 | + |
| 23 | +## `sql` |
| 24 | + |
| 25 | +This package is probably the most important of the project. It has several main roles: |
| 26 | +- Defines the main interfaces used in the rest of the packages `Node`, `Expression`, ... |
| 27 | +- Provides implementations of components used in the rest of the packages `Row`, `Context`, `ProcessList`, `Catalog`, ... |
| 28 | +- Defines the `information_schema` table, which is a special table available in all databases and contains some data about the schemas of other tables. |
| 29 | + |
| 30 | +### `sql/analyzer` |
| 31 | + |
| 32 | +The analyzer is the more complex component of the project. It contains a main component, which is the `Analyzer`, in charge of executing its registered rules on execution trees for resolving some parts, removing redundant data, optimizing things for performance, etc. |
| 33 | + |
| 34 | +There are several phases on the analyzer, because some rules need to be run before others, some need to be executed several times, other just once, etc. |
| 35 | +Inside `rules.go` are all the default rules and the phases in which they're executed. |
| 36 | + |
| 37 | +On top of that, all available rules are defined in this package. Each rule has a specific role in the analyzer. Rules should be as small and atomic as possible and try to do only one job and always produce a tree that is as resolved as the one it received or more. |
| 38 | + |
| 39 | +### `sql/expression` |
| 40 | + |
| 41 | +This package includes the implementation of all the SQL expressions available in go-mysql-server, except functions. Arithmetic operators, logic operators, conversions, etc are implemented here. |
| 42 | + |
| 43 | +Inside `registry.go` there is a registry of all the default functions, even if they're not defined here. |
| 44 | + |
| 45 | +`Inspect` and `Walk` utility functions are provided to inspect expressions. |
| 46 | + |
| 47 | +### `sql/expression/function` |
| 48 | + |
| 49 | +Implementation of all the functions available in go-mysql-server. |
| 50 | + |
| 51 | +### `sql/expression/function/aggregation` |
| 52 | + |
| 53 | +Implementation of all the aggregation functions available in go-mysql-server. |
| 54 | + |
| 55 | +### `sql/index` |
| 56 | + |
| 57 | +Contains the index driver configuration file implementation and other utilities for dealing with index drivers. |
| 58 | + |
| 59 | +### `sql/index/pilosa` |
| 60 | + |
| 61 | +Actual implementation of an index driver. Underneath, it's using a bitmap database called pilosa (hence the name) to implement bitmap indexes. |
| 62 | + |
| 63 | +### `sql/parse` |
| 64 | + |
| 65 | +This package exposes the `Parse` function, which parses a SQL query and translates it into an execution plan. |
| 66 | + |
| 67 | +Parsing is done using `vitess` parser, but sometimes there are queries vitess cannot parse. In this case, custom parsers are used. Otherwise, vitess is used to parse the query and then converted to a go-mysql-server execution plan. |
| 68 | + |
| 69 | +### `sql/plan` |
| 70 | + |
| 71 | +All the different nodes of the execution plan (except for very specific nodes used in some optimisation rules) are defined here. |
| 72 | + |
| 73 | +For example, `SELECT foo FROM bar` is translated into the following plan: |
| 74 | + |
| 75 | +``` |
| 76 | +Project(foo) |
| 77 | + |- Table(bar) |
| 78 | +``` |
| 79 | + |
| 80 | +Which means, the execution plan is a `Project` node projecting `foo` and has a `ResolvedTable`, which is `bar` as its children. |
| 81 | + |
| 82 | +Each node inside this package implements at least the `sql.Node` interface, but it can implement more. `sql.Expressioner`, for example. |
| 83 | + |
| 84 | +Along with the nodes, `Inspect` and `Walk` functions are provided as utilities to inspect an execution tree. |
| 85 | + |
| 86 | +## `server` |
| 87 | + |
| 88 | +Contains all the code to turn an engine into a runnable server that can communicate using the MySQL wire protocol. |
| 89 | + |
| 90 | +## `auth` |
| 91 | + |
| 92 | +This package contains all the code related to the audit log, authentication and permission management in go-mysql-server. |
| 93 | + |
| 94 | +There are two authentication methods: |
| 95 | +- **None:** no authentication needed. |
| 96 | +- **Native:** authentication performed with user and password. Read, write or all permissions can be specified for those users. It can also be configured using a JSON file. |
| 97 | + |
| 98 | +## `internal/regex` |
| 99 | + |
| 100 | +go-mysql-server has multiple regular expression engines, such as oniguruma and the standard Go regexp engine. In this package, a common interface for regular expression engines is defined. |
| 101 | +This means, Go standard library `regexp` package should not be used in any user-facing feature, instead this package should be used. |
| 102 | + |
| 103 | +The default engine is oniguruma, but the Go standard library engine can be used using the `mysql_go_regex` build tag. |
| 104 | + |
| 105 | +## `test` |
| 106 | + |
| 107 | +Test contains pieces that are only used for tests, such as an opentracing tracer that stores spans in memory to be inspected later in the tests. |
| 108 | + |
| 109 | +## `_integration` |
| 110 | + |
| 111 | +To ensure compatibility with some clients, there is a small example connecting and querying a go-mysql-server server from those clients. Each folder corresponds to a different client. |
| 112 | + |
| 113 | +For more info about supported clients see [SUPPORTED_CLIENTS.md](/SUPPORTED_CLIENTS.md). |
| 114 | + |
| 115 | +These integrations tests can be run using this command: |
| 116 | + |
| 117 | +``` |
| 118 | +make TEST=${CLIENT FOLDER NAME} integration |
| 119 | +``` |
| 120 | + |
| 121 | +It will take care of setting up the test server and shutting it down. |
| 122 | + |
| 123 | +## `_example` |
| 124 | + |
| 125 | +A small example of how to use go-mysql-server to create a server and run it. |
| 126 | + |
| 127 | +# Connecting the dots |
| 128 | + |
| 129 | +`server` uses the engine defined in `sql`. |
| 130 | + |
| 131 | +Engine uses audit logs and authentication defined in `auth`, parses using `sql/parse` to convert a query into an execution plan, with nodes defined in `sql/plan` and expressions defined in `sql/expression`, `sql/expression/function` and `sql/expression/function/aggregation`. |
| 132 | + |
| 133 | +After parsing, the obtained execution plan is analyzed using the analyzer defined in `sql/analyzer` and its rules to resolve tables, fields, databases, apply optimisation rules, etc. |
| 134 | + |
| 135 | +If indexes can be used, the analyzer will transform the query so it uses indexes reading from the drivers in `sql/index` (in this case `sql/index/pilosa` because there is only one driver). |
| 136 | + |
| 137 | +Once the plan is analyzed, it will be executed recursively from the top of the tree to the bottom to obtain the results and they will be sent back to the client using the MySQL wire protocol. |
0 commit comments