• 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

80.0
/pkg/pgsql/server/rewrite/rules/pg_casts.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 rules holds the AST transformations the rewriter applies.
18
// Each file is one rule, with its own table-driven test. B1 ships
19
// three rules as proof-of-concept; B2 will port the remaining ~55
20
// regex rules in query_machine.go the same way.
21
package rules
22

23
import (
24
        "strings"
25

26
        "github.com/auxten/postgresql-parser/pkg/sql/sem/tree"
27
)
28

29
// StripPGCasts removes CAST expressions whose target is one of the
30
// Postgres-specific pseudo-types that psql and ORMs emit as
31
// no-op-for-immudb casts:
32
//
33
//        c.oid::regclass
34
//        'foo'::text
35
//        t.typname::name
36
//        x::regtype
37
//
38
// Replaces the compound regex at query_machine.go line 477:
39
//
40
//        `\s*::\s*(regclass|oid|text|name|regtype|regproc|regoper|regnamespace|anyarray)(\s*,|\s*\))?`
41
//
42
// Rationale: these casts were only ever needed to coerce pgwire text
43
// columns into typed values PG planners could optimise around; the
44
// immudb engine handles the raw column types fine, so stripping the
45
// cast leaves the underlying expression unchanged semantically.
46
//
47
// Implementation: walks every Expr in a Statement and replaces
48
// CastExpr nodes whose Type family or name matches the allowlist
49
// with the CastExpr's inner Expr.
50
type StripPGCasts struct{}
51

52
// Name implements rewrite.Rule.
NEW
53
func (StripPGCasts) Name() string { return "StripPGCasts" }
×
54

55
// Apply implements rewrite.Rule.
56
func (s StripPGCasts) Apply(stmt tree.Statement) tree.Statement {
35✔
57
        // Drive the rewrite through walkStatementExprs — we're a
35✔
58
        // single-Expr transform, no Statement-level surgery needed.
35✔
59
        return walkStatementExprs(stmt, stripCastVisitFn)
35✔
60
}
35✔
61

62
// pgStripCastTypeNames is the allowlist of type names that, when
63
// used as the target of a CAST, indicate a PG-compat cast we should
64
// unwrap. Matched case-insensitively against CastExpr.Type.SQLString.
65
//
66
// Matches the regex's alternation exactly:
67
//
68
//        regclass|oid|text|name|regtype|regproc|regoper|regnamespace|anyarray
69
//
70
// Intentionally does NOT include sized-text forms like CHAR(n) —
71
// those are real type conversions the user asked for.
72
var pgStripCastTypeNames = map[string]struct{}{
73
        "regclass":      {},
74
        "oid":           {},
75
        "text":          {},
76
        "name":          {},
77
        "regtype":       {},
78
        "regproc":       {},
79
        "regoper":       {},
80
        "regnamespace":  {},
81
        "anyarray":      {},
82
        // auxten normalises ::text to ::STRING, so accept both spellings.
83
        // The regex path matches "text" in the raw SQL; after parsing,
84
        // the AST Type is STRING. Including both makes the rule survive
85
        // the parse+re-deparse round trip that the regex rule doesn't
86
        // have to deal with.
87
        "string": {},
88
}
89

90
// stripCastVisitFn implements rewrite.SimpleVisitFn semantics for
91
// the CAST unwrap. Returns the inner expression in place of any
92
// CastExpr whose target type is in the allowlist.
93
func stripCastVisitFn(expr tree.Expr) (recurse bool, newExpr tree.Expr, err error) {
44✔
94
        cast, ok := expr.(*tree.CastExpr)
44✔
95
        if !ok {
77✔
96
                return true, expr, nil
33✔
97
        }
33✔
98
        if cast.Type == nil {
11✔
NEW
99
                return true, expr, nil
×
NEW
100
        }
×
101
        typeName := strings.ToLower(cast.Type.SQLString())
11✔
102
        // CockroachDB's SQLString() can include array / precision
11✔
103
        // suffixes — strip at the first non-identifier character so the
11✔
104
        // allowlist comparison works for bare type names.
11✔
105
        if idx := strings.IndexAny(typeName, "( []"); idx > 0 {
11✔
NEW
106
                typeName = typeName[:idx]
×
NEW
107
        }
×
108
        if _, stripMe := pgStripCastTypeNames[typeName]; !stripMe {
13✔
109
                return true, expr, nil
2✔
110
        }
2✔
111
        // Replace this CastExpr with its inner expression. Recurse into
112
        // the replacement so nested casts (rare but possible:
113
        // `c.oid::regclass::text`) collapse fully.
114
        return true, cast.Expr, nil
9✔
115
}
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