Add CUBRID database dialect support#575
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #575 +/- ##
==========================================
+ Coverage 92.22% 93.18% +0.96%
==========================================
Files 138 165 +27
Lines 8382 9360 +978
==========================================
+ Hits 7730 8722 +992
+ Misses 477 467 -10
+ Partials 175 171 -4 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
The codecov check on PR go-jet#575 reported 53.41% patch coverage (164 lines missing), failing the 90% target. This commit addresses the gap with comprehensive unit tests and CI integration test support. Unit test additions (cubrid/ package, 78.6% -> 94.5%): - select_statement: WINDOW clause, AsTable subquery, ORDER BY with NULLS FIRST/LAST, PRECEDING/FOLLOWING window frame offsets - set_statement: INTERSECT_ALL, EXCEPT_ALL (both function and method forms), ORDER_BY/LIMIT/OFFSET chaining, AsTable on set results - insert_statement: MODELS batch insert - replace_statement: MODELS batch replace - update_statement: SET with column assignment expressions - with_statement: WITH, WITH_RECURSIVE, CTE ALIAS (new file) - lateral: LATERAL derived table with AS alias (new file) - values: VALUES table constructor with AS alias (new file) - statement: RawStatement (new file) - functions: LPAD, RPAD, CURRENT_TIME, CURRENT_TIMESTAMP, NOW - cubrid_functions: TIMEDIFF, CURRENT_USER_, DRANDOM with seed, TO_DATETIME with format, TO_TIMESTAMP with format - dialect: argumentToString for []byte, float division (/ operator) - interval_literal: INTERVALd(0), unitType.String(), intervalDebugString Unit test additions (internal/jet/, CUBRID files -> 100%): - clause_cubrid: full serialization tests for all CUBRID-specific clauses with actual data (StartWith, ConnectBy, ConnectBy NOCYCLE, OrderSiblingsBy, MergeInto, MergeUsing, MergeOn, WhenMatched UPDATE/DELETE, WhenNotMatched INSERT, ReplaceInto with/without columns, GetColumns). Also covers all lowercase serialize() wrappers. - cast: CAST expression with dialect operator override path CircleCI configuration (.circleci/config.yml): - Add cubrid/cubrid:11.4 Docker service (port 33000, DB: cubdb) - Add wait-for-CUBRID step (up to 60s with 2s interval) - Add cubrid/... to -coverpkg list in main test run - Add CUBRID integration test step running generator/cubrid/... tests with -tags integration and CUBRID_DSN env var - Merge CUBRID coverage profile into main cover.out before codecov upload
8ce27df to
81a07be
Compare
- Add cubrid/ package: SQL builder dialect for CUBRID 11.x - SELECT, INSERT, UPDATE, DELETE, REPLACE INTO, MERGE INTO - Hierarchical queries (START WITH, CONNECT BY, PRIOR, LEVEL) - CUBRID-specific functions, CAST, INTERVAL, LOCK/UNLOCK - Add generator/cubrid/ package: code generator for CUBRID schema - Table/view metadata extraction, column type mapping - DSN parsing, Pool/HA connection support - Integration tests against CUBRID 11.4 - Add internal/jet/cast.go: shared CAST expression implementation - Add internal/jet/clause_cubrid.go: CUBRID-specific SQL clauses (START WITH, CONNECT BY, ORDER SIBLINGS BY, MERGE, REPLACE INTO) - Update generator/template/: add CUBRID type mappings (short, monetary, string, nchar, clob, set, multiset, etc.) - Update cmd/jet/main.go: add CUBRID as a supported source - Update go.mod: add cubrid-go driver dependency
- Remove local replace directive for cubrid-go (use published module) - Update cubrid-go to latest version with Pool/HA support - Restore go directive to 1.24.0 to match CI toolchain
v0.1.0 declared a non-existent go 1.26.1 directive which broke builds on Go 1.24.x. v0.1.1 fixes this by lowering to go 1.22.
The codecov check on PR go-jet#575 reported 53.41% patch coverage (164 lines missing), failing the 90% target. This commit addresses the gap with comprehensive unit tests and CI integration test support. Unit test additions (cubrid/ package, 78.6% -> 94.5%): - select_statement: WINDOW clause, AsTable subquery, ORDER BY with NULLS FIRST/LAST, PRECEDING/FOLLOWING window frame offsets - set_statement: INTERSECT_ALL, EXCEPT_ALL (both function and method forms), ORDER_BY/LIMIT/OFFSET chaining, AsTable on set results - insert_statement: MODELS batch insert - replace_statement: MODELS batch replace - update_statement: SET with column assignment expressions - with_statement: WITH, WITH_RECURSIVE, CTE ALIAS (new file) - lateral: LATERAL derived table with AS alias (new file) - values: VALUES table constructor with AS alias (new file) - statement: RawStatement (new file) - functions: LPAD, RPAD, CURRENT_TIME, CURRENT_TIMESTAMP, NOW - cubrid_functions: TIMEDIFF, CURRENT_USER_, DRANDOM with seed, TO_DATETIME with format, TO_TIMESTAMP with format - dialect: argumentToString for []byte, float division (/ operator) - interval_literal: INTERVALd(0), unitType.String(), intervalDebugString Unit test additions (internal/jet/, CUBRID files -> 100%): - clause_cubrid: full serialization tests for all CUBRID-specific clauses with actual data (StartWith, ConnectBy, ConnectBy NOCYCLE, OrderSiblingsBy, MergeInto, MergeUsing, MergeOn, WhenMatched UPDATE/DELETE, WhenNotMatched INSERT, ReplaceInto with/without columns, GetColumns). Also covers all lowercase serialize() wrappers. - cast: CAST expression with dialect operator override path CircleCI configuration (.circleci/config.yml): - Add cubrid/cubrid:11.4 Docker service (port 33000, DB: cubdb) - Add wait-for-CUBRID step (up to 60s with 2s interval) - Add cubrid/... to -coverpkg list in main test run - Add CUBRID integration test step running generator/cubrid/... tests with -tags integration and CUBRID_DSN env var - Merge CUBRID coverage profile into main cover.out before codecov upload
- Remove cubridREGEXPLIKEoperator/cubridNOTREGEXPLIKEoperator from dialect.go: these operator overrides were never invoked because REGEXP_LIKE uses the dialect's RegexpLike() method path, not the binary operator override path. The default fallback in dialectImpl.RegexpLike() already outputs correct CUBRID SQL. - Add UPDATE and SHARE RowLock constants to select_statement.go - Add TestSelectFOR covering SELECT ... FOR UPDATE/SHARE - Add TestSelectPRECEDING_FOLLOWING_UNBOUNDED covering toJetFrameOffset UNBOUNDED branch cubrid package unit test coverage: 94.3% → 97.7%
Add tests covering previously uncovered code paths: - dialect.go: ValuesDefaultColumnName, JsonValueEncode lambdas - dialect.go: TRUNC function - insert_statement.go: ON DUPLICATE KEY UPDATE with multiple assignments - select_statement.go: WINDOW().AS() with no arguments, VALUES with default column names - interval_literal.go: INTERVALd hours+microseconds branch - generator/template/process.go: insertedRowAlias CUBRID branch cubrid package unit test coverage: 97.7% → 99.3%
- column_types_test.go: add DEC, CHARACTER, UTIME, VARBIT, LIST, DATETIMELTZ, TIMESTAMPLTZ, CHARACTER VARYING, and default-branch cases - error_path_test.go: unit tests for GenerateDSN (missing DB name), GeneratePool (empty DSN), GenerateHA (invalid DSN), Generate (connection refused) — covers all generator function error paths without requiring a DB - query_set_test.go: mock SQL driver tests for GetTablesMetaData (list error, view error, column error via partial mock), GetEnumsMetaData (nil return), getColumnMetaData (list columns error) Unit-test-only coverage: generator/cubrid 31.9% → 66.4% Remaining success-path lines are covered by the existing integration tests
error_path_test.go: - TestGenerateDSN_ConnectionRefused: covers openConnection error in GenerateDSN - TestGenerateDB_SchemaError: covers metadata.GetSchema error path in GenerateDB - TestGenerateDB_ProcessSchemaError: covers template.ProcessSchema error path using schemaDriver (returns one mock table) + /dev/null as destDir to force fs error - Added schemaDriver and emptyDriver mock SQL drivers query_set_test.go: - TestGetColumnMetaData_Success: covers pkSet + columns construction loops using colsPksDriver (returns one column + one PK) - TestGetColumnMetaData_PKsError: covers ListPrimaryKeys error path using pksErrDriver Coverage summary (unit tests only): - generator/cubrid/query_set.go: 0% → 100% - generator/cubrid/cubrid_generator.go: 31.9% → 89.4% (remaining ~10% are success paths covered by integration tests)
Refactor cubrid_generator.go to inject dependencies via package-level variables:
- sqlOpen: replaces sql.Open("cubrid", ...) in openConnection
- newPool: replaces cubriddriver.NewPool
- newHACluster: replaces cubriddriver.NewHACluster
- poolProvider/haProvider interfaces allow mock implementations in tests
New tests in error_path_test.go:
- TestOpenConnection_Success: success path via sqlOpen mock
- TestOpenConnection_SqlOpenError: sqlOpen failure path
- TestGenerate_Success / TestGenerateDSN_Success: full happy paths
- TestGeneratePool_Success / TestGenerateHA_Success: via mockPool/mockHA
- TestGenerateDB_CustomTemplate: covers len(templates)>0 branch
generator/cubrid unit coverage: 89.4% → 100%
Tests call the SerializerFunc returned by each operator with 0 arguments, triggering the len(expressions) < 2 panic guard. cubrid/dialect.go unit coverage: 93.18% → 100%
|
Hi @go-jet! 👋 Friendly ping — this PR adds first-class CUBRID dialect support. CUBRID is widely used in Korean public-sector and enterprise environments, and this would make go-jet the first type-safe SQL builder for Go to support it natively. All tests pass (including integration tests against CUBRID 11.4), coverage improved from 92.22% to 93.18%, and existing dialects are completely untouched. Would love to get your feedback whenever you have a moment. Thank you! |
|
Thanks, @search5, for the contribution. CUBRID looks like an interesting database, and I That said, I do not currently plan to add support for new dialects in Jet. Due CUBRID also still seems to be a fairly niche database, so adding and maintaining For these reasons, I do not think this is something I can review/merge at the moment, |
Motivation
CUBRID is an open-source relational database widely adopted in Korean public-sector and enterprise environments. Despite its maturity (the current stable release is 11.4), there is no type-safe SQL builder for Go that supports CUBRID natively. Developers working with CUBRID in Go are currently limited to raw SQL strings, which sacrifices the compile-time safety and composability that go-jet provides for PostgreSQL, MySQL, and SQLite.
This PR adds first-class CUBRID support to go-jet, following the same architecture and conventions used by the existing dialects.
What This PR Contains
1.
cubrid/— SQL Builder Dialect PackageA complete SQL builder dialect for CUBRID, including:
SELECT,INSERT,UPDATE,DELETEREPLACE INTO,MERGE INTOSTART WITH,CONNECT BY/CONNECT BY NOCYCLE,ORDER SIBLINGS BYPRIOR(),LEVEL,ROWNUM,CONNECT_BY_ROOT(),CONNECT_BY_ISLEAF,SYS_CONNECT_BY_PATH()NVL,NVL2,DECODE,TO_CHAR,TO_DATE,TO_DATETIME,TRUNC,INCR,DECR, etc.CASTwith CUBRID-native type targetsINTERVALliteral expressionsLOCK/UNLOCKtable statementsSET(UNION, INTERSECT, EXCEPT) operationsWITH(CTE) support2.
generator/cubrid/— Code GeneratorDBConnectionstruct, DSN string, and Pool/HA configurations viacubrid-godriver3.
internal/jet/— Minimal Core Additionscast.go: SharedCastimplementation reusable across dialectsclause_cubrid.go: CUBRID-specific SQL clauses (ClauseStartWith,ClauseConnectBy,ClauseOrderSiblingsBy,ClauseMergeInto,ClauseMergeUsing,ClauseMergeOn,ClauseWhenMatched,ClauseWhenNotMatched,ClauseReplaceInto)4.
generator/template/— Type Mapping Extensionsmodel_template.goandsql_builder_template.go:short,monetary,string,nchar,nchar varying,clob,set,multiset,sequence,list,object,oid,timestampltz,datetimeltz,datetimetz"CUBRID"case toinsertedRowAliasinprocess.go5.
cmd/jet/main.go— CLI Entry Pointcase "cubrid"to the jet CLI generator, supporting both DSN and host/port connection parameters6.
go.modgithub.com/search5/cubrid-godriver dependencyDesign Decisions
mysql/,postgres/,sqlite/,qrm/, and existinginternal/jet/files are completely untouched. All CUBRID support is purely additive.CONNECT BY) andMERGE INTOare not afterthoughts — they have dedicated clause types, proper serialization, and full test coverage.Test Plan
go build ./...passesgo vet ./...passes (excluding pre-existingWriteBytesignature warning)go test ./cubrid/— all SQL builder unit tests passgo test ./generator/cubrid/— all unit tests passgo test -tags integration ./generator/cubrid/— all integration tests pass against CUBRID 11.4go test ./internal/jet/— existing core tests still passgo test ./generator/template/— template tests pass including new CUBRID type cases