Documentation ¶
Index ¶
- Constants
- Variables
- func InitializeEngine(ctx context.Context, tx sql.DB) error
- type GlobalContext
- func (g *GlobalContext) CreateDataset(ctx context.Context, tx sql.DB, schema *common.Schema, caller []byte) (err error)
- func (g *GlobalContext) DeleteDataset(ctx context.Context, tx sql.DB, dbid string, caller []byte) error
- func (g *GlobalContext) Execute(ctx context.Context, tx sql.DB, dbid, query string, values map[string]any) (*sql.ResultSet, error)
- func (g *GlobalContext) GetSchema(_ context.Context, dbid string) (*common.Schema, error)
- func (g *GlobalContext) ListDatasets(_ context.Context, caller []byte) ([]*types.DatasetIdentifier, error)
- func (g *GlobalContext) Procedure(ctx context.Context, tx sql.DB, options *common.ExecutionData) (*sql.ResultSet, error)
Constants ¶
const MaxStackDepth = 1000
MaxStackDepth is the limit on the number of nested procedure calls allowed. This is different from the Go call stack depth, which may be much higher as it depends on the program design. The value 1,000 was empirically selected to be a call stack size of about 1MB and to provide a very high limit that no reasonable schema would exceed (even 100 would suggest a poorly designed schema).
In addition to exorbitant memory required to support a call stack 1 million deep (>1GB), the execution of that many calls can take seconds, even if they do nothing else.
Progressive gas metering may be used in the future to limit resources used by abusive recursive calls, but a hard upper limit will likely be necessary unless the price of an action call is extremely expensive or rises exponentially at each level of the call stack.
Variables ¶
var ( ErrIncorrectNumberOfArguments = errors.New("incorrect number of arguments") ErrPrivateProcedure = errors.New("procedure is private") ErrMutativeProcedure = errors.New("procedure is mutative") ErrMaxStackDepth = errors.New("max call stack depth reached") )
var ErrDatasetNotFound = fmt.Errorf("dataset not found")
Functions ¶
Types ¶
type GlobalContext ¶
type GlobalContext struct {
// contains filtered or unexported fields
}
GlobalContext is the context for the entire execution. It exists for the lifetime of the server. It stores information about deployed datasets in-memory, and provides methods to interact with them.
func NewGlobalContext ¶
func NewGlobalContext(ctx context.Context, db sql.Executor, extensionInitializers map[string]precompiles.Initializer, service *common.Service) (*GlobalContext, error)
NewGlobalContext creates a new global context. It will load any persisted datasets from the datastore. The provided database is only used for construction.
func (*GlobalContext) CreateDataset ¶
func (g *GlobalContext) CreateDataset(ctx context.Context, tx sql.DB, schema *common.Schema, caller []byte) (err error)
CreateDataset deploys a schema. It will create the requisite tables, and perform the required initializations.
func (*GlobalContext) DeleteDataset ¶
func (g *GlobalContext) DeleteDataset(ctx context.Context, tx sql.DB, dbid string, caller []byte) error
DeleteDataset deletes a dataset. It will ensure that the caller is the owner of the dataset.
func (*GlobalContext) Execute ¶
func (g *GlobalContext) Execute(ctx context.Context, tx sql.DB, dbid, query string, values map[string]any) (*sql.ResultSet, error)
Execute executes a SQL statement on a dataset. If the statement is mutative, the tx must also be a sql.AccessModer. It uses Kwil's SQL dialect.
func (*GlobalContext) ListDatasets ¶
func (g *GlobalContext) ListDatasets(_ context.Context, caller []byte) ([]*types.DatasetIdentifier, error)
ListDatasets list datasets deployed by a specific caller. If caller is empty, it will list all datasets.
func (*GlobalContext) Procedure ¶
func (g *GlobalContext) Procedure(ctx context.Context, tx sql.DB, options *common.ExecutionData) (*sql.ResultSet, error)
Procedure calls a procedure on a dataset. It can be given either a readwrite or readonly transaction. If it is given a read-only transaction, it will not be able to execute any procedures that are not `view`.