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

codenotary / immudb / 24841571249

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

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%)

119 existing lines in 18 files now uncovered.

44597 of 52298 relevant lines covered (85.27%)

127591.66 hits per line

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

97.62
/pkg/pgsql/sys/pg_constraint.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_constraint: one row per primary-key or unique-index constraint on
28
// each user table. immudb doesn't yet materialise CHECK or FOREIGN KEY
29
// constraints in the catalog layer, so those contypes are omitted.
30
//
31
// contype ('p'=primary, 'u'=unique) drives psql's constraint-display
32
// block in `\d`. conkey is a PG int2[] of attnums; we emit it as a
33
// braces-wrapped comma-separated list (`{1,2}`) which is the textual
34
// form PG itself uses when array_to_string isn't involved.
35
//
36
// Constraint names: primary-key constraints are named `<table>_pkey`
37
// (psql convention), unique indexes reuse their index name. Matches
38
// what `\d` prints for real PostgreSQL and makes the constraint oid
39
// FNV-stable across restarts.
40
func init() {
13✔
41
        sql.RegisterSystemTable(&sql.SystemTableDef{
13✔
42
                Name: "pg_constraint",
13✔
43
                Columns: []sql.SystemTableColumn{
13✔
44
                        {Name: "oid", Type: sql.IntegerType},
13✔
45
                        {Name: "conname", Type: sql.VarcharType, MaxLen: 128},
13✔
46
                        {Name: "connamespace", Type: sql.IntegerType},
13✔
47
                        {Name: "contype", Type: sql.VarcharType, MaxLen: 1},
13✔
48
                        {Name: "condeferrable", Type: sql.BooleanType},
13✔
49
                        {Name: "condeferred", Type: sql.BooleanType},
13✔
50
                        {Name: "convalidated", Type: sql.BooleanType},
13✔
51
                        {Name: "conrelid", Type: sql.IntegerType},
13✔
52
                        {Name: "contypid", Type: sql.IntegerType},
13✔
53
                        {Name: "conindid", Type: sql.IntegerType},
13✔
54
                        {Name: "conparentid", Type: sql.IntegerType},
13✔
55
                        {Name: "confrelid", Type: sql.IntegerType},
13✔
56
                        {Name: "confupdtype", Type: sql.VarcharType, MaxLen: 1},
13✔
57
                        {Name: "confdeltype", Type: sql.VarcharType, MaxLen: 1},
13✔
58
                        {Name: "confmatchtype", Type: sql.VarcharType, MaxLen: 1},
13✔
59
                        {Name: "conislocal", Type: sql.BooleanType},
13✔
60
                        {Name: "coninhcount", Type: sql.IntegerType},
13✔
61
                        {Name: "connoinherit", Type: sql.BooleanType},
13✔
62
                        {Name: "conkey", Type: sql.VarcharType, MaxLen: 256},
13✔
63
                        {Name: "confkey", Type: sql.VarcharType, MaxLen: 1},
13✔
64
                        {Name: "conpfeqop", Type: sql.VarcharType, MaxLen: 1},
13✔
65
                        {Name: "conppeqop", Type: sql.VarcharType, MaxLen: 1},
13✔
66
                        {Name: "conffeqop", Type: sql.VarcharType, MaxLen: 1},
13✔
67
                        {Name: "conexclop", Type: sql.VarcharType, MaxLen: 1},
13✔
68
                        {Name: "conbin", Type: sql.VarcharType, MaxLen: 1},
13✔
69
                },
13✔
70
                PKColumn: "oid",
13✔
71
                Scan: func(ctx context.Context, tx *sql.SQLTx) ([]*sql.Row, error) {
22✔
72
                        cat := tx.Catalog()
9✔
73
                        if cat == nil {
9✔
NEW
74
                                return nil, nil
×
NEW
75
                        }
×
76
                        tables := cat.GetTables()
9✔
77
                        rows := make([]*sql.Row, 0, len(tables)*2)
9✔
78
                        for _, t := range tables {
18✔
79
                                tableOID := relOID("public", t.Name())
9✔
80
                                for _, idx := range t.GetIndexes() {
19✔
81
                                        switch {
10✔
82
                                        case idx.IsPrimary():
9✔
83
                                                rows = append(rows, rowConstraint(
9✔
84
                                                        t.Name()+"_pkey", "p", tableOID, idx, relOID("public", idx.Name())))
9✔
85
                                        case idx.IsUnique():
1✔
86
                                                rows = append(rows, rowConstraint(
1✔
87
                                                        idx.Name(), "u", tableOID, idx, relOID("public", idx.Name())))
1✔
88
                                        }
89
                                }
90
                        }
91
                        return rows, nil
9✔
92
                },
93
        })
94
}
95

96
func rowConstraint(conname, contype string, tableOID int64, idx *sql.Index, conindid int64) *sql.Row {
10✔
97
        cols := idx.Cols()
10✔
98
        parts := make([]string, len(cols))
10✔
99
        for i, c := range cols {
20✔
100
                parts[i] = strconv.Itoa(int(c.ID()))
10✔
101
        }
10✔
102
        conkey := "{" + strings.Join(parts, ",") + "}"
10✔
103

10✔
104
        return &sql.Row{ValuesByPosition: []sql.TypedValue{
10✔
105
                sql.NewInteger(relOID("pg_constraint", conname)),
10✔
106
                sql.NewVarchar(conname),
10✔
107
                sql.NewInteger(OIDNamespacePublic),
10✔
108
                sql.NewVarchar(contype),
10✔
109
                sql.NewBool(false), // condeferrable
10✔
110
                sql.NewBool(false), // condeferred
10✔
111
                sql.NewBool(true),  // convalidated
10✔
112
                sql.NewInteger(tableOID),
10✔
113
                sql.NewInteger(0), // contypid
10✔
114
                sql.NewInteger(conindid),
10✔
115
                sql.NewInteger(0), // conparentid
10✔
116
                sql.NewInteger(0), // confrelid
10✔
117
                sql.NewVarchar(" "),
10✔
118
                sql.NewVarchar(" "),
10✔
119
                sql.NewVarchar(" "),
10✔
120
                sql.NewBool(true), // conislocal
10✔
121
                sql.NewInteger(0),
10✔
122
                sql.NewBool(true), // connoinherit
10✔
123
                sql.NewVarchar(conkey),
10✔
124
                sql.NewNull(sql.VarcharType),
10✔
125
                sql.NewNull(sql.VarcharType),
10✔
126
                sql.NewNull(sql.VarcharType),
10✔
127
                sql.NewNull(sql.VarcharType),
10✔
128
                sql.NewNull(sql.VarcharType),
10✔
129
                sql.NewNull(sql.VarcharType),
10✔
130
        }}
10✔
131
}
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