• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

codenotary / immudb / 24841644892

23 Apr 2026 02:44PM UTC coverage: 85.279% (-4.0%) from 89.306%
24841644892

push

gh-ci

web-flow
feat: v1.11.0 PostgreSQL compatibility and SQL feature expansion (#2090)

* Add structured audit logging with immutable audit trail

Introduces a new --audit-log flag that records all gRPC operations as
structured JSON events in immudb's tamper-proof KV store. Events are
stored under the audit: key prefix in systemdb, queryable via Scan and
verifiable via VerifiableGet. An async buffered writer ensures minimal
latency impact. Configurable event filtering (all/write/admin) via
--audit-log-events flag.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Add PostgreSQL ORM compatibility layer and verification functions

Extend the pgsql wire protocol with immudb verification functions
(immudb_state, immudb_verify_row, immudb_verify_tx, immudb_history,
immudb_tx) accessible via standard SQL SELECT statements.

Add pg_catalog resolvers (pg_attribute, pg_index, pg_constraint,
pg_type, pg_settings, pg_description) and information_schema
resolvers (tables, columns, schemata, key_column_usage) to support
ORM introspection from Django, SQLAlchemy, GORM, and ActiveRecord.

Add PostgreSQL compatibility functions: current_database,
current_schema, current_user, format_type, pg_encoding_to_char,
pg_get_expr, pg_get_constraintdef, obj_description, col_description,
has_table_privilege, has_schema_privilege, and others.

Add SHOW statement emulation for common ORM config queries and
schema-qualified name stripping for information_schema and public
schema references.

* Implement EXISTS and IN subquery support in SQL engine

Replace the previously stubbed ExistsBoolExp and InSubQueryExp
implementations with working non-correlated subquery execution.

EXISTS subqueries resolve the inner SELECT and check if any rows
are returned. IN subqueries resolve the inner SELECT, iterate the
result set, and compare each value against the outer expression.
Both support NOT variants (NOT EXISTS, NOT IN).

Correlated subqueries (referencing outer query columns) ar... (continued)

7254 of 10471 new or added lines in 124 files covered. (69.28%)

115 existing lines in 18 files now uncovered.

44599 of 52298 relevant lines covered (85.28%)

127676.6 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

97.53
/pkg/pgsql/sys/pg_index.go
1
/*
2
Copyright 2026 Codenotary Inc. All rights reserved.
3

4
SPDX-License-Identifier: BUSL-1.1
5
you may not use this file except in compliance with the License.
6
You may obtain a copy of the License at
7

8
    https://mariadb.com/bsl11/
9

10
Unless required by applicable law or agreed to in writing, software
11
distributed under the License is distributed on an "AS IS" BASIS,
12
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
See the License for the specific language governing permissions and
14
limitations under the License.
15
*/
16

17
package sys
18

19
import (
20
        "context"
21
        "strconv"
22
        "strings"
23

24
        "github.com/codenotary/immudb/embedded/sql"
25
)
26

27
// pg_index: one row per index on a user table. indexrelid points at
28
// the pg_class row for the index (relkind='i'); indrelid points at
29
// the pg_class row for the table the index is on.
30
//
31
// indkey in real PG is an int2vector — a space-separated list of
32
// attnums the index covers. We emit the same textual form as varchar
33
// because immudb SQL doesn't have a native int2vector, and every
34
// client we've seen treats indkey as text anyway (psql parses it as a
35
// space-separated list of ints).
36
func init() {
13✔
37
        sql.RegisterSystemTable(&sql.SystemTableDef{
13✔
38
                Name: "pg_index",
13✔
39
                Columns: []sql.SystemTableColumn{
13✔
40
                        {Name: "indexrelid", Type: sql.IntegerType},
13✔
41
                        {Name: "indrelid", Type: sql.IntegerType},
13✔
42
                        {Name: "indnatts", Type: sql.IntegerType},
13✔
43
                        {Name: "indnkeyatts", Type: sql.IntegerType},
13✔
44
                        {Name: "indisunique", Type: sql.BooleanType},
13✔
45
                        {Name: "indisprimary", Type: sql.BooleanType},
13✔
46
                        {Name: "indisexclusion", Type: sql.BooleanType},
13✔
47
                        {Name: "indimmediate", Type: sql.BooleanType},
13✔
48
                        {Name: "indisclustered", Type: sql.BooleanType},
13✔
49
                        {Name: "indisvalid", Type: sql.BooleanType},
13✔
50
                        {Name: "indcheckxmin", Type: sql.BooleanType},
13✔
51
                        {Name: "indisready", Type: sql.BooleanType},
13✔
52
                        {Name: "indislive", Type: sql.BooleanType},
13✔
53
                        {Name: "indisreplident", Type: sql.BooleanType},
13✔
54
                        {Name: "indkey", Type: sql.VarcharType, MaxLen: 256},
13✔
55
                        {Name: "indcollation", Type: sql.VarcharType, MaxLen: 256},
13✔
56
                        {Name: "indclass", Type: sql.VarcharType, MaxLen: 256},
13✔
57
                        {Name: "indoption", Type: sql.VarcharType, MaxLen: 256},
13✔
58
                        {Name: "indexprs", Type: sql.VarcharType, MaxLen: 1},
13✔
59
                        {Name: "indpred", Type: sql.VarcharType, MaxLen: 1},
13✔
60
                },
13✔
61
                PKColumn: "indexrelid",
13✔
62
                Scan: func(ctx context.Context, tx *sql.SQLTx) ([]*sql.Row, error) {
17✔
63
                        cat := tx.Catalog()
4✔
64
                        if cat == nil {
4✔
NEW
65
                                return nil, nil
×
NEW
66
                        }
×
67
                        tables := cat.GetTables()
4✔
68
                        rows := make([]*sql.Row, 0, len(tables)*2)
4✔
69

4✔
70
                        for _, t := range tables {
8✔
71
                                tableOID := relOID("public", t.Name())
4✔
72
                                for _, idx := range t.GetIndexes() {
9✔
73
                                        rows = append(rows, rowPgIndex(tableOID, t, idx))
5✔
74
                                }
5✔
75
                        }
76
                        return rows, nil
4✔
77
                },
78
        })
79
}
80

81
func rowPgIndex(tableOID int64, t *sql.Table, idx *sql.Index) *sql.Row {
5✔
82
        cols := idx.Cols()
5✔
83

5✔
84
        // Build indkey: space-separated attnum list.
5✔
85
        parts := make([]string, len(cols))
5✔
86
        for i, c := range cols {
10✔
87
                parts[i] = strconv.Itoa(int(c.ID()))
5✔
88
        }
5✔
89
        indkey := strings.Join(parts, " ")
5✔
90

5✔
91
        // indcollation, indclass, indoption: vectors of the same length as
5✔
92
        // indkey, each a zero-value. psql's \d reads them but tolerates all
5✔
93
        // zeros (= default collation / default opclass / default options).
5✔
94
        zeros := make([]string, len(cols))
5✔
95
        for i := range zeros {
10✔
96
                zeros[i] = "0"
5✔
97
        }
5✔
98
        zerosJoined := strings.Join(zeros, " ")
5✔
99

5✔
100
        return &sql.Row{ValuesByPosition: []sql.TypedValue{
5✔
101
                sql.NewInteger(relOID("public", idx.Name())),
5✔
102
                sql.NewInteger(tableOID),
5✔
103
                sql.NewInteger(int64(len(cols))),
5✔
104
                sql.NewInteger(int64(len(cols))), // indnkeyatts — we have no INCLUDE cols
5✔
105
                sql.NewBool(idx.IsUnique()),
5✔
106
                sql.NewBool(idx.IsPrimary()),
5✔
107
                sql.NewBool(false), // indisexclusion
5✔
108
                sql.NewBool(true),  // indimmediate — always; we don't support DEFERRABLE
5✔
109
                sql.NewBool(false),
5✔
110
                sql.NewBool(true), // indisvalid
5✔
111
                sql.NewBool(false),
5✔
112
                sql.NewBool(true),
5✔
113
                sql.NewBool(true),
5✔
114
                sql.NewBool(idx.IsPrimary()), // indisreplident mirrors PK for simplicity
5✔
115
                sql.NewVarchar(indkey),
5✔
116
                sql.NewVarchar(zerosJoined),
5✔
117
                sql.NewVarchar(zerosJoined),
5✔
118
                sql.NewVarchar(zerosJoined),
5✔
119
                sql.NewNull(sql.VarcharType),
5✔
120
                sql.NewNull(sql.VarcharType),
5✔
121
        }}
5✔
122
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc