Skip to content

Commit

Permalink
chore(embedded/sql): Add support for core pg_catalog tables (pg_class…
Browse files Browse the repository at this point in the history
…, pg_namespace, pg_roles)

Signed-off-by: Stefano Scafiti <[email protected]>
  • Loading branch information
ostafen committed Dec 11, 2024
1 parent b7ff0e6 commit 52df5f2
Show file tree
Hide file tree
Showing 23 changed files with 1,215 additions and 331 deletions.
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
*.out
coverage.txt

# Output of goyacc
embedded/sql/y.output

# Editor
.vscode
.idea
Expand Down Expand Up @@ -50,4 +53,4 @@ token_admin

swagger/dist
swagger/swaggerembedded
webconsole/webconsoleembedded
webconsole/webconsoleembedded
24 changes: 24 additions & 0 deletions embedded/sql/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ type Engine struct {
lazyIndexConstraintValidation bool
parseTxMetadata func([]byte) (map[string]interface{}, error)
multidbHandler MultiDBHandler
tableResolvers map[string]TableResolver
}

type MultiDBHandler interface {
Expand All @@ -134,6 +135,11 @@ type MultiDBHandler interface {
ExecPreparedStmts(ctx context.Context, opts *TxOptions, stmts []SQLStmt, params map[string]interface{}) (ntx *SQLTx, committedTxs []*SQLTx, err error)
}

type TableResolver interface {
Table() string
Resolve(ctx context.Context, tx *SQLTx, alias string) (RowReader, error)
}

type User interface {
Username() string
Permission() Permission
Expand Down Expand Up @@ -176,6 +182,10 @@ func NewEngine(st *store.ImmuStore, opts *Options) (*Engine, error) {
return nil, err
}

for _, r := range opts.tableResolvers {
e.registerTableResolver(r.Table(), r)
}

// TODO: find a better way to handle parsing errors
yyErrorVerbose = true

Expand Down Expand Up @@ -728,3 +738,17 @@ func (e *Engine) GetStore() *store.ImmuStore {
func (e *Engine) GetPrefix() []byte {
return e.prefix
}

func (e *Engine) tableResolveFor(tableName string) TableResolver {
if e.tableResolvers == nil {
return nil
}
return e.tableResolvers[tableName]
}

func (e *Engine) registerTableResolver(tableName string, r TableResolver) {
if e.tableResolvers == nil {
e.tableResolvers = make(map[string]TableResolver)
}
e.tableResolvers[tableName] = r
}
59 changes: 59 additions & 0 deletions embedded/sql/engine_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4616,6 +4616,10 @@ func TestOrderBy(t *testing.T) {
directions: []int{1, -1},
positionalRefs: []int{4, 5},
},
{
exps: []string{"weight/(height*height)"},
directions: []int{1},
},
}

runTest := func(t *testing.T, test *test, expectedTempFiles int) []*Row {
Expand Down Expand Up @@ -9552,6 +9556,40 @@ func TestFunctions(t *testing.T) {
})
}

func TestTableResolver(t *testing.T) {
st, err := store.Open(t.TempDir(), store.DefaultOptions().WithMultiIndexing(true))
require.NoError(t, err)
defer closeStore(t, st)

r := &mockTableResolver{
name: "my_table",
cols: []ColDescriptor{
{Column: "varchar_col", Type: VarcharType},
{Column: "int_col", Type: IntegerType},
{Column: "bool_col", Type: BooleanType},
},
values: [][]ValueExp{{NewVarchar("test"), NewInteger(1), NewBool(true)}},
}

engine, err := NewEngine(
st,
DefaultOptions().
WithPrefix(sqlPrefix).
WithTableResolvers(r),
)
require.NoError(t, err)

assertQueryShouldProduceResults(
t,
engine,
"SELECT int_col, varchar_col, bool_col FROM my_table",
`SELECT * FROM (
VALUES
(1, 'test', true)
)`,
)
}

func assertQueryShouldProduceResults(t *testing.T, e *Engine, query, resultQuery string) {
queryReader, err := e.Query(context.Background(), nil, query, nil)
require.NoError(t, err)
Expand All @@ -9572,3 +9610,24 @@ func assertQueryShouldProduceResults(t *testing.T, e *Engine, query, resultQuery
require.Equal(t, expectedRow.ValuesByPosition, actualRow.ValuesByPosition)
}
}

type mockTableResolver struct {
name string
cols []ColDescriptor
values [][]ValueExp
}

func (r *mockTableResolver) Table() string {
return r.name
}

func (r *mockTableResolver) Resolve(ctx context.Context, tx *SQLTx, alias string) (RowReader, error) {
return NewValuesRowReader(
tx,
nil,
r.cols,
false,
r.name,
r.values,
)
}
Loading

0 comments on commit 52df5f2

Please sign in to comment.