Retry create issue to cope with duplicate keys (#7898)

* Retry create issue to cope with duplicate keys

* Use  .SetExpr().Where().Insert()
pull/7993/head
guillep2k 4 years ago committed by techknowlogick
parent 541fab196f
commit 5fe2ec264f
  1. 4
      go.mod
  2. 7
      go.sum
  3. 52
      models/issue.go
  4. 7
      routers/api/v1/repo/pull.go
  5. 7
      routers/repo/pull.go
  6. 538
      vendor/github.com/go-xorm/xorm/.drone.yml
  7. 7
      vendor/github.com/go-xorm/xorm/README.md
  8. 374
      vendor/github.com/go-xorm/xorm/dialect_mssql.go
  9. 18
      vendor/github.com/go-xorm/xorm/dialect_mysql.go
  10. 544
      vendor/github.com/go-xorm/xorm/dialect_oracle.go
  11. 1244
      vendor/github.com/go-xorm/xorm/dialect_postgres.go
  12. 4
      vendor/github.com/go-xorm/xorm/dialect_sqlite3.go
  13. 45
      vendor/github.com/go-xorm/xorm/engine.go
  14. 2
      vendor/github.com/go-xorm/xorm/go.mod
  15. 21
      vendor/github.com/go-xorm/xorm/go.sum
  16. 23
      vendor/github.com/go-xorm/xorm/helpers.go
  17. 2
      vendor/github.com/go-xorm/xorm/session_find.go
  18. 115
      vendor/github.com/go-xorm/xorm/session_get.go
  19. 134
      vendor/github.com/go-xorm/xorm/session_insert.go
  20. 17
      vendor/github.com/go-xorm/xorm/session_update.go
  21. 35
      vendor/github.com/go-xorm/xorm/statement.go
  22. 4
      vendor/modules.txt
  23. 42
      vendor/xorm.io/core/.drone.yml
  24. 4
      vendor/xorm.io/core/README.md
  25. 16
      vendor/xorm.io/core/cache.go
  26. 4
      vendor/xorm.io/core/column.go
  27. 4
      vendor/xorm.io/core/db.go
  28. 20
      vendor/xorm.io/core/dialect.go
  29. 4
      vendor/xorm.io/core/error.go
  30. 20
      vendor/xorm.io/core/filter.go
  31. 8
      vendor/xorm.io/core/go.mod
  32. 14
      vendor/xorm.io/core/go.sum
  33. 4
      vendor/xorm.io/core/ilogger.go
  34. 7
      vendor/xorm.io/core/index.go
  35. 8
      vendor/xorm.io/core/mapper.go
  36. 2
      vendor/xorm.io/core/rows.go
  37. 1
      vendor/xorm.io/core/stmt.go
  38. 9
      vendor/xorm.io/core/table.go
  39. 46
      vendor/xorm.io/core/type.go

@ -45,7 +45,7 @@ require (
github.com/glycerine/goconvey v0.0.0-20190315024820-982ee783a72e // indirect
github.com/go-redis/redis v6.15.2+incompatible
github.com/go-sql-driver/mysql v1.4.1
github.com/go-xorm/xorm v0.7.4
github.com/go-xorm/xorm v0.7.7-0.20190822154023-17592d96b35b
github.com/gogits/chardet v0.0.0-20150115103509-2404f7772561
github.com/gogs/cron v0.0.0-20171120032916-9f6c956d3e14
github.com/google/go-github/v24 v24.0.1
@ -117,5 +117,5 @@ require (
mvdan.cc/xurls/v2 v2.0.0
strk.kbt.io/projects/go/libravatar v0.0.0-20160628055650-5eed7bff870a
xorm.io/builder v0.3.5
xorm.io/core v0.6.3
xorm.io/core v0.7.0
)

@ -143,6 +143,8 @@ github.com/go-xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:9wScpmSP5A3Bk
github.com/go-xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:56xuuqnHyryaerycW3BfssRdxQstACi0Epw/yC5E2xM=
github.com/go-xorm/xorm v0.7.4 h1:g/NgC590SzqV5VKmdRDNe/K3Holw3YJUCXX28r+rFGw=
github.com/go-xorm/xorm v0.7.4/go.mod h1:vpza5fydeRgt+stvo9qgMhSNohYqmNt0I1/D6hkCekA=
github.com/go-xorm/xorm v0.7.7-0.20190822154023-17592d96b35b h1:Y0hWUheXDHpIs7BWtJcykO4d1VOsVDKg1PsP5YJwxxM=
github.com/go-xorm/xorm v0.7.7-0.20190822154023-17592d96b35b/go.mod h1:nqz2TAsuOHWH2yk4FYWtacCGgdbrcdZ5mF1XadqEHls=
github.com/gogits/chardet v0.0.0-20150115103509-2404f7772561 h1:deE7ritpK04PgtpyVOS2TYcQEld9qLCD5b5EbVNOuLA=
github.com/gogits/chardet v0.0.0-20150115103509-2404f7772561/go.mod h1:YgYOrVn3Nj9Tq0EvjmFbphRytDj7JNRoWSStJZWDJTQ=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
@ -430,6 +432,7 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190730183949-1393eb018365/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@ -446,6 +449,7 @@ golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGm
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190606050223-4d9ae51c2468/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190729092621-ff9f1409240a/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI=
golang.org/x/tools v0.0.0-20190731214159-1e85ed8060aa h1:kwa/4M1dbmhZqOIqYiTtbA6JrvPwo1+jqlub2qDXX90=
@ -454,6 +458,7 @@ google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMt
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.1 h1:QzqyMA1tlu6CgqCDUtU9V+ZKhLFT2dkJuANu5QaxI3I=
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
@ -509,3 +514,5 @@ xorm.io/builder v0.3.5 h1:EilU39fvWDxjb1cDaELpYhsF+zziRBhew8xk4pngO+A=
xorm.io/builder v0.3.5/go.mod h1:ZFbByS/KxZI1FKRjL05PyJ4YrK2bcxlUaAxdum5aTR8=
xorm.io/core v0.6.3 h1:n1NhVZt1s2oLw1BZfX2ocIJsHyso259uPgg63BGr37M=
xorm.io/core v0.6.3/go.mod h1:8kz/C6arVW/O9vk3PgCiMJO2hIAm1UcuOL3dSPyZ2qo=
xorm.io/core v0.7.0 h1:hKxuOKWZNeiFQsSuGet/KV8HZ788hclvAl+7azx3tkM=
xorm.io/core v0.7.0/go.mod h1:TuOJjIVa7e3w/rN8tDcAvuLBMtwzdHPbyOzE6Gk1EUI=

@ -5,7 +5,6 @@
package models
import (
"errors"
"fmt"
"path"
"regexp"
@ -74,6 +73,7 @@ var (
const issueTasksRegexpStr = `(^\s*[-*]\s\[[\sx]\]\s.)|(\n\s*[-*]\s\[[\sx]\]\s.)`
const issueTasksDoneRegexpStr = `(^\s*[-*]\s\[[x]\]\s.)|(\n\s*[-*]\s\[[x]\]\s.)`
const issueMaxDupIndexAttempts = 3
func init() {
issueTasksPat = regexp.MustCompile(issueTasksRegexpStr)
@ -1031,36 +1031,9 @@ type NewIssueOptions struct {
IsPull bool
}
// GetMaxIndexOfIssue returns the max index on issue
func GetMaxIndexOfIssue(repoID int64) (int64, error) {
return getMaxIndexOfIssue(x, repoID)
}
func getMaxIndexOfIssue(e Engine, repoID int64) (int64, error) {
var (
maxIndex int64
has bool
err error
)
has, err = e.SQL("SELECT COALESCE((SELECT MAX(`index`) FROM issue WHERE repo_id = ?),0)", repoID).Get(&maxIndex)
if err != nil {
return 0, err
} else if !has {
return 0, errors.New("Retrieve Max index from issue failed")
}
return maxIndex, nil
}
func newIssue(e *xorm.Session, doer *User, opts NewIssueOptions) (err error) {
opts.Issue.Title = strings.TrimSpace(opts.Issue.Title)
maxIndex, err := getMaxIndexOfIssue(e, opts.Issue.RepoID)
if err != nil {
return err
}
opts.Issue.Index = maxIndex + 1
if opts.Issue.MilestoneID > 0 {
milestone, err := getMilestoneByRepoID(e, opts.Issue.RepoID, opts.Issue.MilestoneID)
if err != nil && !IsErrMilestoneNotExist(err) {
@ -1109,10 +1082,31 @@ func newIssue(e *xorm.Session, doer *User, opts NewIssueOptions) (err error) {
}
// Milestone and assignee validation should happen before insert actual object.
if _, err = e.Insert(opts.Issue); err != nil {
// There's no good way to identify a duplicate key error in database/sql; brute force some retries
dupIndexAttempts := issueMaxDupIndexAttempts
for {
_, err := e.SetExpr("`index`", "coalesce(MAX(`index`),0)+1").
Where("repo_id=?", opts.Issue.RepoID).
Insert(opts.Issue)
if err == nil {
break
}
dupIndexAttempts--
if dupIndexAttempts <= 0 {
return err
}
}
inserted, err := getIssueByID(e, opts.Issue.ID)
if err != nil {
return err
}
// Patch Index with the value calculated by the database
opts.Issue.Index = inserted.Index
if opts.Issue.MilestoneID > 0 {
if err = changeMilestoneAssign(e, doer, opts.Issue, -1); err != nil {
return err

@ -252,15 +252,8 @@ func CreatePullRequest(ctx *context.APIContext, form api.CreatePullRequestOption
deadlineUnix = timeutil.TimeStamp(form.Deadline.Unix())
}
maxIndex, err := models.GetMaxIndexOfIssue(repo.ID)
if err != nil {
ctx.ServerError("GetPatch", err)
return
}
prIssue := &models.Issue{
RepoID: repo.ID,
Index: maxIndex + 1,
Title: form.Title,
PosterID: ctx.User.ID,
Poster: ctx.User,

@ -710,15 +710,8 @@ func CompareAndPullRequestPost(ctx *context.Context, form auth.CreateIssueForm)
return
}
maxIndex, err := models.GetMaxIndexOfIssue(repo.ID)
if err != nil {
ctx.ServerError("GetPatch", err)
return
}
pullIssue := &models.Issue{
RepoID: repo.ID,
Index: maxIndex + 1,
Title: form.Title,
PosterID: ctx.User.ID,
Poster: ctx.User,

@ -1,125 +1,431 @@
---
kind: pipeline
name: matrix-1
platform:
os: linux
arch: amd64
clone:
disable: true
workspace:
base: /go
path: src/github.com/go-xorm/xorm
steps:
- name: git
pull: default
image: plugins/git:next
settings:
depth: 50
tags: true
- name: init_postgres
pull: default
image: postgres:9.5
commands:
- "until psql -U postgres -d xorm_test -h pgsql \\\n -c \"SELECT 1;\" >/dev/null 2>&1; do sleep 1; done\n"
- "psql -U postgres -d xorm_test -h pgsql \\\n -c \"create schema xorm;\"\n"
- name: build
pull: default
image: golang:1.10
commands:
- go get -t -d -v ./...
- go get -u xorm.io/core
- go get -u xorm.io/builder
- go build -v
when:
event:
- push
- pull_request
- name: test-sqlite
pull: default
image: golang:1.10
commands:
- go get -u github.com/wadey/gocovmerge
- "go test -v -race -db=\"sqlite3\" -conn_str=\"./test.db\" -coverprofile=coverage1-1.txt -covermode=atomic"
- "go test -v -race -db=\"sqlite3\" -conn_str=\"./test.db\" -cache=true -coverprofile=coverage1-2.txt -covermode=atomic"
when:
event:
- push
- pull_request
- name: test-mysql
pull: default
image: golang:1.10
commands:
- "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(mysql)/xorm_test\" -coverprofile=coverage2-1.txt -covermode=atomic"
- "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(mysql)/xorm_test\" -cache=true -coverprofile=coverage2-2.txt -covermode=atomic"
when:
event:
- push
- pull_request
- name: test-mysql-utf8mb4
pull: default
image: golang:1.10
commands:
- "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(mysql)/xorm_test?charset=utf8mb4\" -coverprofile=coverage2.1-1.txt -covermode=atomic"
- "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(mysql)/xorm_test?charset=utf8mb4\" -cache=true -coverprofile=coverage2.1-2.txt -covermode=atomic"
when:
event:
- push
- pull_request
- name: test-mymysql
pull: default
image: golang:1.10
commands:
- "go test -v -race -db=\"mymysql\" -conn_str=\"tcp:mysql:3306*xorm_test/root/\" -coverprofile=coverage3-1.txt -covermode=atomic"
- "go test -v -race -db=\"mymysql\" -conn_str=\"tcp:mysql:3306*xorm_test/root/\" -cache=true -coverprofile=coverage3-2.txt -covermode=atomic"
when:
event:
- push
- pull_request
- name: test-postgres
pull: default
image: golang:1.10
commands:
- "go test -v -race -db=\"postgres\" -conn_str=\"postgres://postgres:@pgsql/xorm_test?sslmode=disable\" -coverprofile=coverage4-1.txt -covermode=atomic"
- "go test -v -race -db=\"postgres\" -conn_str=\"postgres://postgres:@pgsql/xorm_test?sslmode=disable\" -cache=true -coverprofile=coverage4-2.txt -covermode=atomic"
when:
event:
- push
- pull_request
- name: test-postgres-schema
pull: default
image: golang:1.10
commands:
- "go test -v -race -db=\"postgres\" -conn_str=\"postgres://postgres:@pgsql/xorm_test?sslmode=disable\" -schema=xorm -coverprofile=coverage5-1.txt -covermode=atomic"
- "go test -v -race -db=\"postgres\" -conn_str=\"postgres://postgres:@pgsql/xorm_test?sslmode=disable\" -schema=xorm -cache=true -coverprofile=coverage5-2.txt -covermode=atomic"
- gocovmerge coverage1-1.txt coverage1-2.txt coverage2-1.txt coverage2-2.txt coverage2.1-1.txt coverage2.1-2.txt coverage3-1.txt coverage3-2.txt coverage4-1.txt coverage4-2.txt coverage5-1.txt coverage5-2.txt > coverage.txt
when:
event:
- push
- pull_request
services:
- name: mysql
pull: default
image: mysql:5.7
environment:
MYSQL_ALLOW_EMPTY_PASSWORD: yes
MYSQL_DATABASE: xorm_test
when:
event:
- push
- tag
- pull_request
- name: pgsql
pull: default
image: postgres:9.5
environment:
POSTGRES_DB: xorm_test
POSTGRES_USER: postgres
when:
event:
- push
- tag
- pull_request
---
kind: pipeline
name: matrix-2
platform:
os: linux
arch: amd64
clone:
disable: true
workspace:
base: /go
path: src/github.com/go-xorm/xorm
steps:
- name: git
pull: default
image: plugins/git:next
settings:
depth: 50
tags: true
- name: init_postgres
pull: default
image: postgres:9.5
commands:
- "until psql -U postgres -d xorm_test -h pgsql \\\n -c \"SELECT 1;\" >/dev/null 2>&1; do sleep 1; done\n"
- "psql -U postgres -d xorm_test -h pgsql \\\n -c \"create schema xorm;\"\n"
- name: build
pull: default
image: golang:1.11
commands:
- go get -t -d -v ./...
- go get -u xorm.io/core
- go get -u xorm.io/builder
- GO111MODULE=off go build -v
when:
event:
- push
- pull_request
- name: build-gomod
pull: default
image: golang:1.11
environment:
GOPROXY: "https://goproxy.cn"
commands:
- GO111MODULE=on go build -v
when:
event:
- push
- pull_request
- name: test-sqlite
pull: default
image: golang:1.11
commands:
- go get -u github.com/wadey/gocovmerge
- "go test -v -race -db=\"sqlite3\" -conn_str=\"./test.db\" -coverprofile=coverage1-1.txt -covermode=atomic"
- "go test -v -race -db=\"sqlite3\" -conn_str=\"./test.db\" -cache=true -coverprofile=coverage1-2.txt -covermode=atomic"
when:
event:
- push
- pull_request
- name: test-mysql
pull: default
image: golang:1.11
commands:
- "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(mysql)/xorm_test\" -coverprofile=coverage2-1.txt -covermode=atomic"
- "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(mysql)/xorm_test\" -cache=true -coverprofile=coverage2-2.txt -covermode=atomic"
when:
event:
- push
- pull_request
- name: test-mysql-utf8mb4
pull: default
image: golang:1.11
commands:
- "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(mysql)/xorm_test?charset=utf8mb4\" -coverprofile=coverage2.1-1.txt -covermode=atomic"
- "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(mysql)/xorm_test?charset=utf8mb4\" -cache=true -coverprofile=coverage2.1-2.txt -covermode=atomic"
when:
event:
- push
- pull_request
- name: test-mymysql
pull: default
image: golang:1.11
commands:
- "go test -v -race -db=\"mymysql\" -conn_str=\"tcp:mysql:3306*xorm_test/root/\" -coverprofile=coverage3-1.txt -covermode=atomic"
- "go test -v -race -db=\"mymysql\" -conn_str=\"tcp:mysql:3306*xorm_test/root/\" -cache=true -coverprofile=coverage3-2.txt -covermode=atomic"
when:
event:
- push
- pull_request
- name: test-postgres
pull: default
image: golang:1.11
commands:
- "go test -v -race -db=\"postgres\" -conn_str=\"postgres://postgres:@pgsql/xorm_test?sslmode=disable\" -coverprofile=coverage4-1.txt -covermode=atomic"
- "go test -v -race -db=\"postgres\" -conn_str=\"postgres://postgres:@pgsql/xorm_test?sslmode=disable\" -cache=true -coverprofile=coverage4-2.txt -covermode=atomic"
when:
event:
- push
- pull_request
- name: test-postgres-schema
pull: default
image: golang:1.11
commands:
- "go test -v -race -db=\"postgres\" -conn_str=\"postgres://postgres:@pgsql/xorm_test?sslmode=disable\" -schema=xorm -coverprofile=coverage5-1.txt -covermode=atomic"
- "go test -v -race -db=\"postgres\" -conn_str=\"postgres://postgres:@pgsql/xorm_test?sslmode=disable\" -schema=xorm -cache=true -coverprofile=coverage5-2.txt -covermode=atomic"
- gocovmerge coverage1-1.txt coverage1-2.txt coverage2-1.txt coverage2-2.txt coverage2.1-1.txt coverage2.1-2.txt coverage3-1.txt coverage3-2.txt coverage4-1.txt coverage4-2.txt coverage5-1.txt coverage5-2.txt > coverage.txt
when:
event:
- push
- pull_request
services:
- name: mysql
pull: default
image: mysql:5.7
environment:
MYSQL_ALLOW_EMPTY_PASSWORD: yes
MYSQL_DATABASE: xorm_test
when:
event:
- push
- tag
- pull_request
- name: pgsql
pull: default
image: postgres:9.5
environment:
POSTGRES_DB: xorm_test
POSTGRES_USER: postgres
when:
event:
- push
- tag
- pull_request
---
kind: pipeline
name: matrix-3
platform:
os: linux
arch: amd64
clone:
git:
image: plugins/git:next
disable: true
workspace:
base: /go
path: src/github.com/go-xorm/xorm
steps:
- name: git
pull: default
image: plugins/git:next
settings:
depth: 50
tags: true
- name: init_postgres
pull: default
image: postgres:9.5
commands:
- "until psql -U postgres -d xorm_test -h pgsql \\\n -c \"SELECT 1;\" >/dev/null 2>&1; do sleep 1; done\n"
- "psql -U postgres -d xorm_test -h pgsql \\\n -c \"create schema xorm;\"\n"
- name: build
pull: default
image: golang:1.12
commands:
- go get -t -d -v ./...
- go get -u xorm.io/core
- go get -u xorm.io/builder
- GO111MODULE=off go build -v
when:
event:
- push
- pull_request
- name: build-gomod
pull: default
image: golang:1.12
environment:
GOPROXY: "https://goproxy.cn"
commands:
- GO111MODULE=on go build -v
when:
event:
- push
- pull_request
- name: test-sqlite
pull: default
image: golang:1.12
commands:
- go get -u github.com/wadey/gocovmerge
- "go test -v -race -db=\"sqlite3\" -conn_str=\"./test.db\" -coverprofile=coverage1-1.txt -covermode=atomic"
- "go test -v -race -db=\"sqlite3\" -conn_str=\"./test.db\" -cache=true -coverprofile=coverage1-2.txt -covermode=atomic"
when:
event:
- push
- pull_request
- name: test-mysql
pull: default
image: golang:1.12
commands:
- "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(mysql)/xorm_test\" -coverprofile=coverage2-1.txt -covermode=atomic"
- "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(mysql)/xorm_test\" -cache=true -coverprofile=coverage2-2.txt -covermode=atomic"
when:
event:
- push
- pull_request
- name: test-mysql-utf8mb4
pull: default
image: golang:1.12
commands:
- "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(mysql)/xorm_test?charset=utf8mb4\" -coverprofile=coverage2.1-1.txt -covermode=atomic"
- "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(mysql)/xorm_test?charset=utf8mb4\" -cache=true -coverprofile=coverage2.1-2.txt -covermode=atomic"
when:
event:
- push
- pull_request
- name: test-mymysql
pull: default
image: golang:1.12
commands:
- "go test -v -race -db=\"mymysql\" -conn_str=\"tcp:mysql:3306*xorm_test/root/\" -coverprofile=coverage3-1.txt -covermode=atomic"
- "go test -v -race -db=\"mymysql\" -conn_str=\"tcp:mysql:3306*xorm_test/root/\" -cache=true -coverprofile=coverage3-2.txt -covermode=atomic"
when:
event:
- push
- pull_request
- name: test-postgres
pull: default
image: golang:1.12
commands:
- "go test -v -race -db=\"postgres\" -conn_str=\"postgres://postgres:@pgsql/xorm_test?sslmode=disable\" -coverprofile=coverage4-1.txt -covermode=atomic"
- "go test -v -race -db=\"postgres\" -conn_str=\"postgres://postgres:@pgsql/xorm_test?sslmode=disable\" -cache=true -coverprofile=coverage4-2.txt -covermode=atomic"
when:
event:
- push
- pull_request
- name: test-postgres-schema
pull: default
image: golang:1.12
commands:
- "go test -v -race -db=\"postgres\" -conn_str=\"postgres://postgres:@pgsql/xorm_test?sslmode=disable\" -schema=xorm -coverprofile=coverage5-1.txt -covermode=atomic"
- "go test -v -race -db=\"postgres\" -conn_str=\"postgres://postgres:@pgsql/xorm_test?sslmode=disable\" -schema=xorm -cache=true -coverprofile=coverage5-2.txt -covermode=atomic"
- gocovmerge coverage1-1.txt coverage1-2.txt coverage2-1.txt coverage2-2.txt coverage2.1-1.txt coverage2.1-2.txt coverage3-1.txt coverage3-2.txt coverage4-1.txt coverage4-2.txt coverage5-1.txt coverage5-2.txt > coverage.txt
when:
event:
- push
- pull_request
services:
mysql:
image: mysql:5.7
environment:
- MYSQL_DATABASE=xorm_test
- MYSQL_ALLOW_EMPTY_PASSWORD=yes
when:
event: [ push, tag, pull_request ]
pgsql:
image: postgres:9.5
environment:
- POSTGRES_USER=postgres
- POSTGRES_DB=xorm_test
when:
event: [ push, tag, pull_request ]
#mssql:
# image: microsoft/mssql-server-linux:2017-CU11
# environment:
# - ACCEPT_EULA=Y
# - SA_PASSWORD=yourStrong(!)Password
# - MSSQL_PID=Developer
# commands:
# - echo 'CREATE DATABASE xorm_test' > create.sql
# - /opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P yourStrong(!)Password -i "create.sql"
matrix:
GO_VERSION:
- 1.8
- 1.9
- 1.10
- 1.11
pipeline:
init_postgres:
image: postgres:9.5
commands:
# wait for postgres service to become available
- |
until psql -U postgres -d xorm_test -h pgsql \
-c "SELECT 1;" >/dev/null 2>&1; do sleep 1; done
# query the database
- |
psql -U postgres -d xorm_test -h pgsql \
-c "create schema xorm;"
build:
image: golang:${GO_VERSION}
commands:
- go get -t -d -v ./...
- go get -u xorm.io/core
- go get -u xorm.io/builder
- go build -v
when:
event: [ push, pull_request ]
test-sqlite:
image: golang:${GO_VERSION}
commands:
- go get -u github.com/wadey/gocovmerge
- go test -v -race -db="sqlite3" -conn_str="./test.db" -coverprofile=coverage1-1.txt -covermode=atomic
- go test -v -race -db="sqlite3" -conn_str="./test.db" -cache=true -coverprofile=coverage1-2.txt -covermode=atomic
when:
event: [ push, pull_request ]
test-mysql:
image: golang:${GO_VERSION}
commands:
- go test -v -race -db="mysql" -conn_str="root:@tcp(mysql)/xorm_test" -coverprofile=coverage2-1.txt -covermode=atomic
- go test -v -race -db="mysql" -conn_str="root:@tcp(mysql)/xorm_test" -cache=true -coverprofile=coverage2-2.txt -covermode=atomic
when:
event: [ push, pull_request ]
test-mysql-utf8mb4:
image: golang:${GO_VERSION}
commands:
- go test -v -race -db="mysql" -conn_str="root:@tcp(mysql)/xorm_test?charset=utf8mb4" -coverprofile=coverage2.1-1.txt -covermode=atomic
- go test -v -race -db="mysql" -conn_str="root:@tcp(mysql)/xorm_test?charset=utf8mb4" -cache=true -coverprofile=coverage2.1-2.txt -covermode=atomic
when:
event: [ push, pull_request ]
test-mymysql:
image: golang:${GO_VERSION}
commands:
- go test -v -race -db="mymysql" -conn_str="tcp:mysql:3306*xorm_test/root/" -coverprofile=coverage3-1.txt -covermode=atomic
- go test -v -race -db="mymysql" -conn_str="tcp:mysql:3306*xorm_test/root/" -cache=true -coverprofile=coverage3-2.txt -covermode=atomic
when:
event: [ push, pull_request ]
test-postgres:
image: golang:${GO_VERSION}
commands:
- go test -v -race -db="postgres" -conn_str="postgres://postgres:@pgsql/xorm_test?sslmode=disable" -coverprofile=coverage4-1.txt -covermode=atomic
- go test -v -race -db="postgres" -conn_str="postgres://postgres:@pgsql/xorm_test?sslmode=disable" -cache=true -coverprofile=coverage4-2.txt -covermode=atomic
when:
event: [ push, pull_request ]
test-postgres-schema:
image: golang:${GO_VERSION}
commands:
- go test -v -race -db="postgres" -conn_str="postgres://postgres:@pgsql/xorm_test?sslmode=disable" -schema=xorm -coverprofile=coverage5-1.txt -covermode=atomic
- go test -v -race -db="postgres" -conn_str="postgres://postgres:@pgsql/xorm_test?sslmode=disable" -schema=xorm -cache=true -coverprofile=coverage5-2.txt -covermode=atomic
- gocovmerge coverage1-1.txt coverage1-2.txt coverage2-1.txt coverage2-2.txt coverage2.1-1.txt coverage2.1-2.txt coverage3-1.txt coverage3-2.txt coverage4-1.txt coverage4-2.txt coverage5-1.txt coverage5-2.txt > coverage.txt
when:
event: [ push, pull_request ]
#coverage:
# image: robertstettner/drone-codecov
# secrets: [ codecov_token ]
# files:
# - coverage.txt
# when:
# event: [ push, pull_request ]
# branch: [ master ]
- name: mysql
pull: default
image: mysql:5.7
environment:
MYSQL_ALLOW_EMPTY_PASSWORD: yes
MYSQL_DATABASE: xorm_test
when:
event:
- push
- tag
- pull_request
- name: pgsql
pull: default
image: postgres:9.5
environment:
POSTGRES_DB: xorm_test
POSTGRES_USER: postgres
when:
event:
- push
- tag
- pull_request

@ -284,6 +284,13 @@ counts, err := engine.Count(&user)
// SELECT count(*) AS total FROM user
```
* `FindAndCount` combines function `Find` with `Count` which is usually used in query by page
```Go
var users []User
counts, err := engine.FindAndCount(&users)
```
* `Sum` sum functions
```Go

@ -16,191 +16,191 @@ import (
var (
mssqlReservedWords = map[string]bool{
"ADD": true,
"EXTERNAL": true,
"PROCEDURE": true,
"ALL": true,
"FETCH": true,
"PUBLIC": true,
"ALTER": true,
"FILE": true,
"RAISERROR": true,
"AND": true,
"FILLFACTOR": true,
"READ": true,
"ANY": true,
"FOR": true,
"READTEXT": true,
"AS": true,
"FOREIGN": true,
"RECONFIGURE": true,
"ASC": true,
"FREETEXT": true,
"REFERENCES": true,
"AUTHORIZATION": true,
"FREETEXTTABLE": true,
"REPLICATION": true,
"BACKUP": true,
"FROM": true,
"RESTORE": true,
"BEGIN": true,
"FULL": true,
"RESTRICT": true,
"BETWEEN": true,
"FUNCTION": true,
"RETURN": true,
"BREAK": true,
"GOTO": true,
"REVERT": true,
"BROWSE": true,
"GRANT": true,
"REVOKE": true,
"BULK": true,
"GROUP": true,
"RIGHT": true,
"BY": true,
"HAVING": true,
"ROLLBACK": true,
"CASCADE": true,
"HOLDLOCK": true,
"ROWCOUNT": true,
"CASE": true,
"IDENTITY": true,
"ROWGUIDCOL": true,
"CHECK": true,
"IDENTITY_INSERT": true,
"RULE": true,
"CHECKPOINT": true,
"IDENTITYCOL": true,
"SAVE": true,
"CLOSE": true,
"IF": true,
"SCHEMA": true,
"CLUSTERED": true,
"IN": true,
"SECURITYAUDIT": true,
"COALESCE": true,
"INDEX": true,
"SELECT": true,
"COLLATE": true,
"INNER": true,
"SEMANTICKEYPHRASETABLE": true,
"COLUMN": true,
"INSERT": true,
"ADD": true,
"EXTERNAL": true,
"PROCEDURE": true,
"ALL": true,
"FETCH": true,
"PUBLIC": true,
"ALTER": true,
"FILE": true,
"RAISERROR": true,
"AND": true,
"FILLFACTOR": true,
"READ": true,
"ANY": true,
"FOR": true,
"READTEXT": true,
"AS": true,
"FOREIGN": true,
"RECONFIGURE": true,
"ASC": true,
"FREETEXT": true,
"REFERENCES": true,
"AUTHORIZATION": true,
"FREETEXTTABLE": true,
"REPLICATION": true,
"BACKUP": true,
"FROM": true,
"RESTORE": true,
"BEGIN": true,
"FULL": true,
"RESTRICT": true,
"BETWEEN": true,
"FUNCTION": true,
"RETURN": true,
"BREAK": true,
"GOTO": true,
"REVERT": true,
"BROWSE": true,
"GRANT": true,
"REVOKE": true,
"BULK": true,
"GROUP": true,
"RIGHT": true,
"BY": true,
"HAVING": true,
"ROLLBACK": true,
"CASCADE": true,
"HOLDLOCK": true,
"ROWCOUNT": true,
"CASE": true,
"IDENTITY": true,
"ROWGUIDCOL": true,
"CHECK": true,
"IDENTITY_INSERT": true,
"RULE": true,
"CHECKPOINT": true,
"IDENTITYCOL": true,
"SAVE": true,
"CLOSE": true,
"IF": true,
"SCHEMA": true,
"CLUSTERED": true,
"IN": true,
"SECURITYAUDIT": true,
"COALESCE": true,
"INDEX": true,
"SELECT": true,
"COLLATE": true,
"INNER": true,
"SEMANTICKEYPHRASETABLE": true,
"COLUMN": true,
"INSERT": true,
"SEMANTICSIMILARITYDETAILSTABLE": true,
"COMMIT": true,
"INTERSECT": true,
"SEMANTICSIMILARITYTABLE": true,
"COMPUTE": true,
"INTO": true,
"SESSION_USER": true,
"CONSTRAINT": true,
"IS": true,
"SET": true,
"CONTAINS": true,
"JOIN": true,
"SETUSER": true,
"CONTAINSTABLE": true,
"KEY": true,
"SHUTDOWN": true,
"CONTINUE": true,
"KILL": true,
"SOME": true,
"CONVERT": true,
"LEFT": true,
"STATISTICS": true,
"CREATE": true,
"LIKE": true,
"SYSTEM_USER": true,
"CROSS": true,
"LINENO": true,
"TABLE": true,
"CURRENT": true,
"LOAD": true,
"TABLESAMPLE": true,
"CURRENT_DATE": true,
"MERGE": true,
"TEXTSIZE": true,
"CURRENT_TIME": true,
"NATIONAL": true,
"THEN": true,
"CURRENT_TIMESTAMP": true,
"NOCHECK": true,
"TO": true,
"CURRENT_USER": true,
"NONCLUSTERED": true,
"TOP": true,
"CURSOR": true,
"NOT": true,
"TRAN": true,
"DATABASE": true,
"NULL": true,
"TRANSACTION": true,
"DBCC": true,
"NULLIF": true,
"TRIGGER": true,
"DEALLOCATE": true,
"OF": true,
"TRUNCATE": true,
"DECLARE": true,
"OFF": true,
"TRY_CONVERT": true,
"DEFAULT": true,
"OFFSETS": true,
"TSEQUAL": true,
"DELETE": true,
"ON": true,
"UNION": true,
"DENY": true,
"OPEN": true,
"UNIQUE": true,
"DESC": true,
"OPENDATASOURCE": true,
"UNPIVOT": true,
"DISK": true,
"OPENQUERY": true,
"UPDATE": true,
"DISTINCT": true,
"OPENROWSET": true,
"UPDATETEXT": true,
"DISTRIBUTED": true,
"OPENXML": true,
"USE": true,
"DOUBLE": true,
"OPTION": true,
"USER": true,
"DROP": true,
"OR": true,
"VALUES": true,
"DUMP": true,
"ORDER": true,
"VARYING": true,
"ELSE": true,
"OUTER": true,
"VIEW": true,
"END": true,
"OVER": true,
"WAITFOR": true,
"ERRLVL": true,
"PERCENT": true,
"WHEN": true,
"ESCAPE": true,
"PIVOT": true,
"WHERE": true,
"EXCEPT": true,
"PLAN": true,
"WHILE": true,
"EXEC": true,
"PRECISION": true,
"WITH": true,
"EXECUTE": true,
"PRIMARY": true,
"WITHIN": true,
"EXISTS": true,
"PRINT": true,
"WRITETEXT": true,
"EXIT": true,
"PROC": true,
"COMMIT": true,
"INTERSECT": true,
"SEMANTICSIMILARITYTABLE": true,
"COMPUTE": true,
"INTO": true,
"SESSION_USER": true,
"CONSTRAINT": true,
"IS": true,
"SET": true,
"CONTAINS": true,
"JOIN": true,
"SETUSER": true,
"CONTAINSTABLE": true,
"KEY": true,
"SHUTDOWN": true,
"CONTINUE": true,
"KILL": true,
"SOME": true,
"CONVERT": true,
"LEFT": true,
"STATISTICS": true,
"CREATE": true,
"LIKE": true,
"SYSTEM_USER": true,
"CROSS": true,
"LINENO": true,
"TABLE": true,
"CURRENT": true,
"LOAD": true,
"TABLESAMPLE": true,
"CURRENT_DATE": true,
"MERGE": true,
"TEXTSIZE": true,
"CURRENT_TIME": true,
"NATIONAL": true,
"THEN": true,
"CURRENT_TIMESTAMP": true,
"NOCHECK": true,
"TO": true,
"CURRENT_USER": true,
"NONCLUSTERED": true,
"TOP": true,
"CURSOR": true,
"NOT": true,
"TRAN": true,
"DATABASE": true,
"NULL": true,
"TRANSACTION": true,
"DBCC": true,
"NULLIF": true,
"TRIGGER": true,
"DEALLOCATE": true,
"OF": true,
"TRUNCATE": true,
"DECLARE": true,
"OFF": true,
"TRY_CONVERT": true,
"DEFAULT": true,
"OFFSETS": true,
"TSEQUAL": true,
"DELETE": true,
"ON": true,
"UNION": true,
"DENY": true,
"OPEN": true,
"UNIQUE": true,
"DESC": true,
"OPENDATASOURCE": true,
"UNPIVOT": true,
"DISK": true,
"OPENQUERY": true,
"UPDATE": true,
"DISTINCT": true,
"OPENROWSET": true,
"UPDATETEXT": true,
"DISTRIBUTED": true,
"OPENXML": true,
"USE": true,
"DOUBLE": true,
"OPTION": true,
"USER": true,
"DROP": true,
"OR": true,
"VALUES": true,
"DUMP": true,
"ORDER": true,
"VARYING": true,
"ELSE": true,
"OUTER": true,
"VIEW": true,
"END": true,
"OVER": true,
"WAITFOR": true,
"ERRLVL": true,
"PERCENT": true,
"WHEN": true,
"ESCAPE": true,
"PIVOT": true,
"WHERE": true,
"EXCEPT": true,
"PLAN": true,
"WHILE": true,
"EXEC": true,
"PRECISION": true,
"WITH": true,
"EXECUTE": true,
"PRIMARY": true,
"WITHIN": true,
"EXISTS": true,
"PRINT": true,
"WRITETEXT": true,
"EXIT": true,
"PROC": true,
}
)
@ -286,10 +286,6 @@ func (db *mssql) Quote(name string) string {
return "\"" + name + "\""
}
func (db *mssql) QuoteStr() string {
return "\""
}
func (db *mssql) SupportEngine() bool {
return false
}
@ -507,7 +503,7 @@ func (db *mssql) CreateTableSql(table *core.Table, tableName, storeEngine, chars
sql = "IF NOT EXISTS (SELECT [name] FROM sys.tables WHERE [name] = '" + tableName + "' ) CREATE TABLE "
sql += db.QuoteStr() + tableName + db.QuoteStr() + " ("
sql += db.Quote(tableName) + " ("
pkList := table.PrimaryKeys

@ -220,7 +220,7 @@ func (db *mysql) SqlType(c *core.Column) string {
case core.TimeStampz:
res = core.Char
c.Length = 64
case core.Enum: //mysql enum
case core.Enum: // mysql enum
res = core.Enum
res += "("
opts := ""
@ -229,7 +229,7 @@ func (db *mysql) SqlType(c *core.Column) string {
}
res += strings.TrimLeft(opts, ",")
res += ")"
case core.Set: //mysql set
case core.Set: // mysql set
res = core.Set
res += "("
opts := ""
@ -278,10 +278,6 @@ func (db *mysql) Quote(name string) string {
return "`" + name + "`"
}
func (db *mysql) QuoteStr() string {
return "`"
}
func (db *mysql) SupportEngine() bool {
return true
}
@ -360,7 +356,7 @@ func (db *mysql) GetColumns(tableName string) ([]string, map[string]*core.Column
var len1, len2 int
if len(cts) == 2 {
idx := strings.Index(cts[1], ")")
if colType == core.Enum && cts[1][0] == '\'' { //enum
if colType == core.Enum && cts[1][0] == '\'' { // enum
options := strings.Split(cts[1][0:idx], ",")
col.EnumOptions = make(map[string]int)
for k, v := range options {
@ -408,7 +404,7 @@ func (db *mysql) GetColumns(tableName string) ([]string, map[string]*core.Column
col.IsPrimaryKey = true
}
if colKey == "UNI" {
//col.is
// col.is
}
if extra == "auto_increment" {
@ -554,12 +550,10 @@ func (db *mysql) CreateTableSql(table *core.Table, tableName, storeEngine, chars
if len(charset) == 0 {
charset = db.URI().Charset
}
}
if len(charset) != 0 {
sql += " DEFAULT CHARSET " + charset
}
if db.rowFormat != "" {
sql += " ROW_FORMAT=" + db.rowFormat
@ -633,7 +627,7 @@ func (p *mysqlDriver) Parse(driverName, dataSourceName string) (*core.Uri, error
`\/(?P<dbname>.*?)` + // /dbname
`(?:\?(?P<params>[^\?]*))?$`) // [?param1=value1&paramN=valueN]
matches := dsnPattern.FindStringSubmatch(dataSourceName)
//tlsConfigRegister := make(map[string]*tls.Config)
// tlsConfigRegister := make(map[string]*tls.Config)
names := dsnPattern.SubexpNames()
uri := &core.Uri{DbType: core.MYSQL}

@ -230,271 +230,271 @@ var (
"LOGGING": true,
"LOGICAL_READS_PER_CALL": true,
"LOGICAL_READS_PER_SESSION": true,
"LONG": true,
"MANAGE": true,
"MASTER": true,
"MAX": true,
"MAXARCHLOGS": true,
"MAXDATAFILES": true,
"MAXEXTENTS": true,
"MAXINSTANCES": true,
"MAXLOGFILES": true,
"MAXLOGHISTORY": true,
"MAXLOGMEMBERS": true,
"MAXSIZE": true,
"MAXTRANS": true,
"MAXVALUE": true,
"MIN": true,
"MEMBER": true,
"MINIMUM": true,
"MINEXTENTS": true,
"MINUS": true,
"MINVALUE": true,
"MLSLABEL": true,
"MLS_LABEL_FORMAT": true,
"MODE": true,
"MODIFY": true,
"MOUNT": true,
"MOVE": true,
"MTS_DISPATCHERS": true,
"MULTISET": true,
"NATIONAL": true,
"NCHAR": true,
"NCHAR_CS": true,
"NCLOB": true,
"NEEDED": true,
"NESTED": true,
"NETWORK": true,
"NEW": true,
"NEXT": true,
"NOARCHIVELOG": true,
"NOAUDIT": true,
"NOCACHE": true,
"NOCOMPRESS": true,
"NOCYCLE": true,
"NOFORCE": true,
"NOLOGGING": true,
"NOMAXVALUE": true,
"NOMINVALUE": true,
"NONE": true,
"NOORDER": true,
"NOOVERRIDE": true,
"NOPARALLEL": true,
"NOREVERSE": true,
"NORMAL": true,
"NOSORT": true,
"NOT": true,
"NOTHING": true,
"NOWAIT": true,
"NULL": true,
"NUMBER": true,
"NUMERIC": true,
"NVARCHAR2": true,
"OBJECT": true,
"OBJNO": true,
"OBJNO_REUSE": true,
"OF": true,
"OFF": true,
"OFFLINE": true,
"OID": true,
"OIDINDEX": true,
"OLD": true,
"ON": true,
"ONLINE": true,
"ONLY": true,
"OPCODE": true,
"OPEN": true,
"OPTIMAL": true,
"OPTIMIZER_GOAL": true,
"OPTION": true,
"OR": true,
"ORDER": true,
"ORGANIZATION": true,
"OSLABEL": true,
"OVERFLOW": true,
"OWN": true,
"PACKAGE": true,
"PARALLEL": true,
"PARTITION": true,
"PASSWORD": true,
"PASSWORD_GRACE_TIME": true,
"PASSWORD_LIFE_TIME": true,
"PASSWORD_LOCK_TIME": true,
"PASSWORD_REUSE_MAX": true,
"PASSWORD_REUSE_TIME": true,
"PASSWORD_VERIFY_FUNCTION": true,
"PCTFREE": true,
"PCTINCREASE": true,
"PCTTHRESHOLD": true,
"PCTUSED": true,
"PCTVERSION": true,
"PERCENT": true,
"PERMANENT": true,
"PLAN": true,
"PLSQL_DEBUG": true,
"POST_TRANSACTION": true,
"PRECISION": true,
"PRESERVE": true,
"PRIMARY": true,
"PRIOR": true,
"PRIVATE": true,
"PRIVATE_SGA": true,
"PRIVILEGE": true,
"PRIVILEGES": true,
"PROCEDURE": true,
"PROFILE": true,
"PUBLIC": true,
"PURGE": true,
"QUEUE": true,
"QUOTA": true,
"RANGE": true,
"RAW": true,
"RBA": true,
"READ": true,
"READUP": true,
"REAL": true,
"REBUILD": true,
"RECOVER": true,
"RECOVERABLE": true,
"RECOVERY": true,
"REF": true,
"REFERENCES": true,
"REFERENCING": true,
"REFRESH": true,
"RENAME": true,
"REPLACE": true,
"RESET": true,
"RESETLOGS": true,
"RESIZE": true,
"RESOURCE": true,
"RESTRICTED": true,
"RETURN": true,
"RETURNING": true,
"REUSE": true,
"REVERSE": true,
"REVOKE": true,
"ROLE": true,
"ROLES": true,
"ROLLBACK": true,
"ROW": true,
"ROWID": true,
"ROWNUM": true,
"ROWS": true,
"RULE": true,