Skip to content

Commit 2797081

Browse files
Merge pull request #63 from oracle-samples/joboon-SupportUnquotedIdentifiers
Joboon - support unquoted identifiers
2 parents 8a144c5 + 70ef685 commit 2797081

File tree

10 files changed

+203
-50
lines changed

10 files changed

+203
-50
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.vscode

oracle/common.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -454,19 +454,19 @@ func QuoteIdentifier(identifier string) string {
454454
// - plsqlBuilder: The builder to write the PL/SQL code into.
455455
// - dbNames: The slice containing the column names.
456456
// - table: The table name
457-
func writeTableRecordCollectionDecl(plsqlBuilder *strings.Builder, dbNames []string, table string) {
457+
func writeTableRecordCollectionDecl(db *gorm.DB, plsqlBuilder *strings.Builder, dbNames []string, table string) {
458458
// Declare a record where each element has the same structure as a row from the given table
459459
plsqlBuilder.WriteString(" TYPE t_record IS RECORD (\n")
460460
for i, field := range dbNames {
461461
if i > 0 {
462462
plsqlBuilder.WriteString(",\n")
463463
}
464464
plsqlBuilder.WriteString(" ")
465-
writeQuotedIdentifier(plsqlBuilder, field)
465+
db.QuoteTo(plsqlBuilder, field)
466466
plsqlBuilder.WriteString(" ")
467-
writeQuotedIdentifier(plsqlBuilder, table)
467+
db.QuoteTo(plsqlBuilder, table)
468468
plsqlBuilder.WriteString(".")
469-
writeQuotedIdentifier(plsqlBuilder, field)
469+
db.QuoteTo(plsqlBuilder, field)
470470
plsqlBuilder.WriteString("%TYPE")
471471
}
472472
plsqlBuilder.WriteString("\n")

oracle/create.go

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ func buildBulkMergePLSQL(db *gorm.DB, createValues clause.Values, onConflictClau
289289

290290
// Start PL/SQL block
291291
plsqlBuilder.WriteString("DECLARE\n")
292-
writeTableRecordCollectionDecl(&plsqlBuilder, stmt.Schema.DBNames, stmt.Table)
292+
writeTableRecordCollectionDecl(db, &plsqlBuilder, stmt.Schema.DBNames, stmt.Table)
293293
plsqlBuilder.WriteString(" l_affected_records t_records;\n")
294294

295295
// Create array types and variables for each column
@@ -323,7 +323,7 @@ func buildBulkMergePLSQL(db *gorm.DB, createValues clause.Values, onConflictClau
323323
// FORALL with MERGE and RETURNING BULK COLLECT INTO
324324
plsqlBuilder.WriteString(fmt.Sprintf(" FORALL i IN 1..%d\n", len(createValues.Values)))
325325
plsqlBuilder.WriteString(" MERGE INTO ")
326-
writeQuotedIdentifier(&plsqlBuilder, stmt.Table)
326+
db.QuoteTo(&plsqlBuilder, stmt.Table)
327327
plsqlBuilder.WriteString(" t\n")
328328
// Build USING clause
329329
plsqlBuilder.WriteString(" USING (SELECT ")
@@ -332,7 +332,7 @@ func buildBulkMergePLSQL(db *gorm.DB, createValues clause.Values, onConflictClau
332332
plsqlBuilder.WriteString(", ")
333333
}
334334
plsqlBuilder.WriteString(fmt.Sprintf("l_col_%d_array(i) AS ", idx))
335-
writeQuotedIdentifier(&plsqlBuilder, column.Name)
335+
db.QuoteTo(&plsqlBuilder, column.Name)
336336
}
337337
plsqlBuilder.WriteString(" FROM DUAL) s\n")
338338

@@ -344,9 +344,9 @@ func buildBulkMergePLSQL(db *gorm.DB, createValues clause.Values, onConflictClau
344344
plsqlBuilder.WriteString(" AND ")
345345
}
346346
plsqlBuilder.WriteString("t.")
347-
writeQuotedIdentifier(&plsqlBuilder, conflictCol.Name)
347+
db.QuoteTo(&plsqlBuilder, conflictCol.Name)
348348
plsqlBuilder.WriteString(" = s.")
349-
writeQuotedIdentifier(&plsqlBuilder, conflictCol.Name)
349+
db.QuoteTo(&plsqlBuilder, conflictCol.Name)
350350
}
351351
plsqlBuilder.WriteString(")\n")
352352

@@ -371,9 +371,9 @@ func buildBulkMergePLSQL(db *gorm.DB, createValues clause.Values, onConflictClau
371371
plsqlBuilder.WriteString(", ")
372372
}
373373
plsqlBuilder.WriteString("t.")
374-
writeQuotedIdentifier(&plsqlBuilder, column.Name)
374+
db.QuoteTo(&plsqlBuilder, column.Name)
375375
plsqlBuilder.WriteString(" = s.")
376-
writeQuotedIdentifier(&plsqlBuilder, column.Name)
376+
db.QuoteTo(&plsqlBuilder, column.Name)
377377
updateCount++
378378
}
379379
}
@@ -405,9 +405,9 @@ func buildBulkMergePLSQL(db *gorm.DB, createValues clause.Values, onConflictClau
405405
plsqlBuilder.WriteString(", ")
406406
}
407407
plsqlBuilder.WriteString("t.")
408-
writeQuotedIdentifier(&plsqlBuilder, column.Name)
408+
db.QuoteTo(&plsqlBuilder, column.Name)
409409
plsqlBuilder.WriteString(" = s.")
410-
writeQuotedIdentifier(&plsqlBuilder, column.Name)
410+
db.QuoteTo(&plsqlBuilder, column.Name)
411411
updateCount++
412412
}
413413
}
@@ -427,9 +427,9 @@ func buildBulkMergePLSQL(db *gorm.DB, createValues clause.Values, onConflictClau
427427
}
428428
}
429429
plsqlBuilder.WriteString(" WHEN MATCHED THEN UPDATE SET t.")
430-
writeQuotedIdentifier(&plsqlBuilder, noopCol)
431-
plsqlBuilder.WriteString(" = s.")
432-
writeQuotedIdentifier(&plsqlBuilder, noopCol)
430+
db.QuoteTo(&plsqlBuilder, noopCol)
431+
plsqlBuilder.WriteString(" = t.")
432+
db.QuoteTo(&plsqlBuilder, noopCol)
433433
plsqlBuilder.WriteString("\n")
434434
}
435435

@@ -444,7 +444,7 @@ func buildBulkMergePLSQL(db *gorm.DB, createValues clause.Values, onConflictClau
444444
if insertCount > 0 {
445445
plsqlBuilder.WriteString(", ")
446446
}
447-
writeQuotedIdentifier(&plsqlBuilder, column.Name)
447+
db.QuoteTo(&plsqlBuilder, column.Name)
448448
insertCount++
449449
}
450450
}
@@ -459,7 +459,7 @@ func buildBulkMergePLSQL(db *gorm.DB, createValues clause.Values, onConflictClau
459459
plsqlBuilder.WriteString(", ")
460460
}
461461
plsqlBuilder.WriteString("s.")
462-
writeQuotedIdentifier(&plsqlBuilder, column.Name)
462+
db.QuoteTo(&plsqlBuilder, column.Name)
463463
insertCount++
464464
}
465465
}
@@ -475,7 +475,7 @@ func buildBulkMergePLSQL(db *gorm.DB, createValues clause.Values, onConflictClau
475475
if insertCount > 0 {
476476
plsqlBuilder.WriteString(", ")
477477
}
478-
writeQuotedIdentifier(&plsqlBuilder, column.Name)
478+
db.QuoteTo(&plsqlBuilder, column.Name)
479479
insertCount++
480480
}
481481
}
@@ -489,7 +489,7 @@ func buildBulkMergePLSQL(db *gorm.DB, createValues clause.Values, onConflictClau
489489
plsqlBuilder.WriteString(", ")
490490
}
491491
plsqlBuilder.WriteString("s.")
492-
writeQuotedIdentifier(&plsqlBuilder, column.Name)
492+
db.QuoteTo(&plsqlBuilder, column.Name)
493493
insertCount++
494494
}
495495
}
@@ -503,7 +503,7 @@ func buildBulkMergePLSQL(db *gorm.DB, createValues clause.Values, onConflictClau
503503
if i > 0 {
504504
plsqlBuilder.WriteString(", ")
505505
}
506-
writeQuotedIdentifier(&plsqlBuilder, column)
506+
db.QuoteTo(&plsqlBuilder, column)
507507
}
508508
plsqlBuilder.WriteString("\n BULK COLLECT INTO l_affected_records;\n")
509509

@@ -514,7 +514,7 @@ func buildBulkMergePLSQL(db *gorm.DB, createValues clause.Values, onConflictClau
514514
if field := findFieldByDBName(schema, column); field != nil {
515515
stmt.Vars = append(stmt.Vars, sql.Out{Dest: createTypedDestination(field)})
516516
plsqlBuilder.WriteString(fmt.Sprintf(" IF l_affected_records.COUNT > %d THEN :%d := l_affected_records(%d).", rowIdx, outParamIndex+1, rowIdx+1))
517-
writeQuotedIdentifier(&plsqlBuilder, column)
517+
db.QuoteTo(&plsqlBuilder, column)
518518
plsqlBuilder.WriteString("; END IF;\n")
519519
outParamIndex++
520520
}
@@ -548,7 +548,7 @@ func buildBulkInsertOnlyPLSQL(db *gorm.DB, createValues clause.Values) {
548548

549549
// Start PL/SQL block
550550
plsqlBuilder.WriteString("DECLARE\n")
551-
writeTableRecordCollectionDecl(&plsqlBuilder, stmt.Schema.DBNames, stmt.Table)
551+
writeTableRecordCollectionDecl(db, &plsqlBuilder, stmt.Schema.DBNames, stmt.Table)
552552
plsqlBuilder.WriteString(" l_inserted_records t_records;\n")
553553

554554
// Create array types and variables for each column
@@ -582,14 +582,14 @@ func buildBulkInsertOnlyPLSQL(db *gorm.DB, createValues clause.Values) {
582582
// FORALL with RETURNING BULK COLLECT INTO
583583
plsqlBuilder.WriteString(fmt.Sprintf(" FORALL i IN 1..%d\n", len(createValues.Values)))
584584
plsqlBuilder.WriteString(" INSERT INTO ")
585-
writeQuotedIdentifier(&plsqlBuilder, stmt.Table)
585+
db.QuoteTo(&plsqlBuilder, stmt.Table)
586586
plsqlBuilder.WriteString(" (")
587587
// Add column names
588588
for i, column := range createValues.Columns {
589589
if i > 0 {
590590
plsqlBuilder.WriteString(", ")
591591
}
592-
writeQuotedIdentifier(&plsqlBuilder, column.Name)
592+
db.QuoteTo(&plsqlBuilder, column.Name)
593593
}
594594
plsqlBuilder.WriteString(") VALUES (")
595595

@@ -609,7 +609,7 @@ func buildBulkInsertOnlyPLSQL(db *gorm.DB, createValues clause.Values) {
609609
if i > 0 {
610610
plsqlBuilder.WriteString(", ")
611611
}
612-
writeQuotedIdentifier(&plsqlBuilder, column)
612+
db.QuoteTo(&plsqlBuilder, column)
613613
}
614614
plsqlBuilder.WriteString("\n BULK COLLECT INTO l_inserted_records;\n")
615615

@@ -618,7 +618,7 @@ func buildBulkInsertOnlyPLSQL(db *gorm.DB, createValues clause.Values) {
618618
for rowIdx := 0; rowIdx < len(createValues.Values); rowIdx++ {
619619
for _, column := range allColumns {
620620
var columnBuilder strings.Builder
621-
writeQuotedIdentifier(&columnBuilder, column)
621+
db.QuoteTo(&columnBuilder, column)
622622
quotedColumn := columnBuilder.String()
623623

624624
if field := findFieldByDBName(schema, column); field != nil {

oracle/delete.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -255,13 +255,13 @@ func buildBulkDeletePLSQL(db *gorm.DB) {
255255

256256
// Start PL/SQL block
257257
plsqlBuilder.WriteString("DECLARE\n")
258-
writeTableRecordCollectionDecl(&plsqlBuilder, stmt.Schema.DBNames, stmt.Table)
258+
writeTableRecordCollectionDecl(db, &plsqlBuilder, stmt.Schema.DBNames, stmt.Table)
259259
plsqlBuilder.WriteString(" l_deleted_records t_records;\n")
260260
plsqlBuilder.WriteString("BEGIN\n")
261261

262262
// Build DELETE statement
263263
plsqlBuilder.WriteString(" DELETE FROM ")
264-
writeQuotedIdentifier(&plsqlBuilder, stmt.Table)
264+
db.QuoteTo(&plsqlBuilder, stmt.Table)
265265

266266
// Add WHERE clause if it exists
267267
if whereClause, hasWhere := stmt.Clauses["WHERE"]; hasWhere {
@@ -278,7 +278,7 @@ func buildBulkDeletePLSQL(db *gorm.DB) {
278278
if i > 0 {
279279
plsqlBuilder.WriteString(", ")
280280
}
281-
writeQuotedIdentifier(&plsqlBuilder, column)
281+
db.QuoteTo(&plsqlBuilder, column)
282282

283283
}
284284
plsqlBuilder.WriteString("\n BULK COLLECT INTO l_deleted_records;\n")
@@ -297,7 +297,7 @@ func buildBulkDeletePLSQL(db *gorm.DB) {
297297

298298
plsqlBuilder.WriteString(fmt.Sprintf(" IF l_deleted_records.COUNT > %d THEN\n", rowIdx))
299299
plsqlBuilder.WriteString(fmt.Sprintf(" :%d := l_deleted_records(%d).", outParamIndex+1, rowIdx+1))
300-
writeQuotedIdentifier(&plsqlBuilder, column)
300+
db.QuoteTo(&plsqlBuilder, column)
301301
plsqlBuilder.WriteString(";\n")
302302
plsqlBuilder.WriteString(" END IF;\n")
303303
outParamIndex++
@@ -324,9 +324,9 @@ func buildWhereClause(db *gorm.DB, plsqlBuilder *strings.Builder, expressions []
324324
case clause.Eq:
325325
// Write the column name
326326
if columnName, ok := e.Column.(string); ok {
327-
writeQuotedIdentifier(plsqlBuilder, columnName)
327+
db.QuoteTo(plsqlBuilder, columnName)
328328
} else if columnExpr, ok := e.Column.(clause.Column); ok {
329-
writeQuotedIdentifier(plsqlBuilder, columnExpr.Name)
329+
db.QuoteTo(plsqlBuilder, columnExpr.Name)
330330
} else {
331331
plsqlBuilder.WriteString(fmt.Sprintf("%v", e.Column))
332332
}
@@ -342,9 +342,9 @@ func buildWhereClause(db *gorm.DB, plsqlBuilder *strings.Builder, expressions []
342342

343343
case clause.IN:
344344
if columnName, ok := e.Column.(string); ok {
345-
writeQuotedIdentifier(plsqlBuilder, columnName)
345+
db.QuoteTo(plsqlBuilder, columnName)
346346
} else if columnExpr, ok := e.Column.(clause.Column); ok {
347-
writeQuotedIdentifier(plsqlBuilder, columnExpr.Name)
347+
db.QuoteTo(plsqlBuilder, columnExpr.Name)
348348
} else {
349349
plsqlBuilder.WriteString(fmt.Sprintf("%v", e.Column))
350350
}

oracle/oracle.go

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -61,11 +61,14 @@ import (
6161
_ "github.com/godror/godror"
6262
)
6363

64+
const DefaultDriverName string = "godror"
65+
6466
type Config struct {
65-
DriverName string
66-
DataSourceName string
67-
Conn *sql.DB
68-
DefaultStringSize uint
67+
DriverName string
68+
DataSourceName string
69+
Conn *sql.DB
70+
DefaultStringSize uint
71+
SkipQuoteIdentifiers bool
6972
}
7073

7174
type Dialector struct {
@@ -79,7 +82,7 @@ func (d Dialector) Name() string {
7982

8083
// Open creates a new godror Dialector with the given DSN
8184
func Open(dsn string) gorm.Dialector {
82-
return &Dialector{Config: &Config{DriverName: "godror", DataSourceName: dsn}}
85+
return &Dialector{Config: &Config{DataSourceName: dsn}}
8386
}
8487

8588
// New creates a new Dialector with the given config
@@ -89,6 +92,10 @@ func New(config Config) gorm.Dialector {
8992

9093
// Initializes the database connection
9194
func (d Dialector) Initialize(db *gorm.DB) (err error) {
95+
if d.DriverName == "" {
96+
d.DriverName = DefaultDriverName
97+
}
98+
9299
d.DefaultStringSize = 4000
93100

94101
config := &callbacks.Config{
@@ -237,9 +244,13 @@ func (d Dialector) BindVarTo(writer clause.Writer, stmt *gorm.Statement, v inter
237244

238245
// Manages quoting of identifiers
239246
func (d Dialector) QuoteTo(writer clause.Writer, str string) {
240-
var builder strings.Builder
241-
writeQuotedIdentifier(&builder, str)
242-
writer.WriteString(builder.String())
247+
out := str
248+
if !d.SkipQuoteIdentifiers {
249+
var builder strings.Builder
250+
writeQuotedIdentifier(&builder, str)
251+
out = builder.String()
252+
}
253+
_, _ = writer.WriteString(out)
243254
}
244255

245256
var numericPlaceholder = regexp.MustCompile(`:(\d+)`)

oracle/update.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -476,21 +476,21 @@ func buildUpdatePLSQL(db *gorm.DB) {
476476

477477
// Start PL/SQL block
478478
plsqlBuilder.WriteString("DECLARE\n")
479-
writeTableRecordCollectionDecl(&plsqlBuilder, stmt.Schema.DBNames, stmt.Table)
479+
writeTableRecordCollectionDecl(db, &plsqlBuilder, stmt.Schema.DBNames, stmt.Table)
480480
plsqlBuilder.WriteString(" l_updated_records t_records;\n")
481481
plsqlBuilder.WriteString("BEGIN\n")
482482

483483
// Build UPDATE statement
484484
plsqlBuilder.WriteString(" UPDATE ")
485-
writeQuotedIdentifier(&plsqlBuilder, stmt.Table)
485+
db.QuoteTo(&plsqlBuilder, stmt.Table)
486486
plsqlBuilder.WriteString(" SET ")
487487

488488
// Add SET assignments - handle both regular values and expressions
489489
for i, assignment := range set {
490490
if i > 0 {
491491
plsqlBuilder.WriteString(", ")
492492
}
493-
writeQuotedIdentifier(&plsqlBuilder, assignment.Column.Name)
493+
db.QuoteTo(&plsqlBuilder, assignment.Column.Name)
494494
plsqlBuilder.WriteString(" = ")
495495

496496
// Check if the value is a clause.Expr (like gorm.Expr)
@@ -528,7 +528,7 @@ func buildUpdatePLSQL(db *gorm.DB) {
528528
if i > 0 {
529529
plsqlBuilder.WriteString(", ")
530530
}
531-
writeQuotedIdentifier(&plsqlBuilder, column)
531+
db.QuoteTo(&plsqlBuilder, column)
532532
}
533533
plsqlBuilder.WriteString("\n BULK COLLECT INTO l_updated_records;\n")
534534

@@ -559,7 +559,7 @@ func buildUpdatePLSQL(db *gorm.DB) {
559559
// Add the assignment to PL/SQL with correct parameter reference
560560
plsqlBuilder.WriteString(fmt.Sprintf(" IF l_updated_records.COUNT > %d THEN\n", rowIdx))
561561
plsqlBuilder.WriteString(fmt.Sprintf(" :%d := l_updated_records(%d).", paramIndex, rowIdx+1))
562-
writeQuotedIdentifier(&plsqlBuilder, column)
562+
db.QuoteTo(&plsqlBuilder, column)
563563
plsqlBuilder.WriteString(";\n")
564564
plsqlBuilder.WriteString(" END IF;\n")
565565
}

tests/.gitignore

Lines changed: 0 additions & 1 deletion
This file was deleted.

0 commit comments

Comments
 (0)