statement.go 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673
  1. package gorm
  2. import (
  3. "context"
  4. "database/sql"
  5. "database/sql/driver"
  6. "fmt"
  7. "reflect"
  8. "sort"
  9. "strconv"
  10. "strings"
  11. "sync"
  12. "gorm.io/gorm/clause"
  13. "gorm.io/gorm/logger"
  14. "gorm.io/gorm/schema"
  15. "gorm.io/gorm/utils"
  16. )
  17. // Statement statement
  18. type Statement struct {
  19. *DB
  20. TableExpr *clause.Expr
  21. Table string
  22. Model interface{}
  23. Unscoped bool
  24. Dest interface{}
  25. ReflectValue reflect.Value
  26. Clauses map[string]clause.Clause
  27. BuildClauses []string
  28. Distinct bool
  29. Selects []string // selected columns
  30. Omits []string // omit columns
  31. Joins []join
  32. Preloads map[string][]interface{}
  33. Settings sync.Map
  34. ConnPool ConnPool
  35. Schema *schema.Schema
  36. Context context.Context
  37. RaiseErrorOnNotFound bool
  38. SkipHooks bool
  39. SQL strings.Builder
  40. Vars []interface{}
  41. CurDestIndex int
  42. attrs []interface{}
  43. assigns []interface{}
  44. scopes []func(*DB) *DB
  45. }
  46. type join struct {
  47. Name string
  48. Conds []interface{}
  49. }
  50. // StatementModifier statement modifier interface
  51. type StatementModifier interface {
  52. ModifyStatement(*Statement)
  53. }
  54. // WriteString write string
  55. func (stmt *Statement) WriteString(str string) (int, error) {
  56. return stmt.SQL.WriteString(str)
  57. }
  58. // WriteByte write byte
  59. func (stmt *Statement) WriteByte(c byte) error {
  60. return stmt.SQL.WriteByte(c)
  61. }
  62. // WriteQuoted write quoted value
  63. func (stmt *Statement) WriteQuoted(value interface{}) {
  64. stmt.QuoteTo(&stmt.SQL, value)
  65. }
  66. // QuoteTo write quoted value to writer
  67. func (stmt *Statement) QuoteTo(writer clause.Writer, field interface{}) {
  68. switch v := field.(type) {
  69. case clause.Table:
  70. if v.Name == clause.CurrentTable {
  71. if stmt.TableExpr != nil {
  72. stmt.TableExpr.Build(stmt)
  73. } else {
  74. stmt.DB.Dialector.QuoteTo(writer, stmt.Table)
  75. }
  76. } else if v.Raw {
  77. writer.WriteString(v.Name)
  78. } else {
  79. stmt.DB.Dialector.QuoteTo(writer, v.Name)
  80. }
  81. if v.Alias != "" {
  82. writer.WriteByte(' ')
  83. stmt.DB.Dialector.QuoteTo(writer, v.Alias)
  84. }
  85. case clause.Column:
  86. if v.Table != "" {
  87. if v.Table == clause.CurrentTable {
  88. stmt.DB.Dialector.QuoteTo(writer, stmt.Table)
  89. } else {
  90. stmt.DB.Dialector.QuoteTo(writer, v.Table)
  91. }
  92. writer.WriteByte('.')
  93. }
  94. if v.Name == clause.PrimaryKey {
  95. if stmt.Schema == nil {
  96. stmt.DB.AddError(ErrModelValueRequired)
  97. } else if stmt.Schema.PrioritizedPrimaryField != nil {
  98. stmt.DB.Dialector.QuoteTo(writer, stmt.Schema.PrioritizedPrimaryField.DBName)
  99. } else if len(stmt.Schema.DBNames) > 0 {
  100. stmt.DB.Dialector.QuoteTo(writer, stmt.Schema.DBNames[0])
  101. }
  102. } else if v.Raw {
  103. writer.WriteString(v.Name)
  104. } else {
  105. stmt.DB.Dialector.QuoteTo(writer, v.Name)
  106. }
  107. if v.Alias != "" {
  108. writer.WriteString(" AS ")
  109. stmt.DB.Dialector.QuoteTo(writer, v.Alias)
  110. }
  111. case []clause.Column:
  112. writer.WriteByte('(')
  113. for idx, d := range v {
  114. if idx > 0 {
  115. writer.WriteString(",")
  116. }
  117. stmt.QuoteTo(writer, d)
  118. }
  119. writer.WriteByte(')')
  120. case string:
  121. stmt.DB.Dialector.QuoteTo(writer, v)
  122. case []string:
  123. writer.WriteByte('(')
  124. for idx, d := range v {
  125. if idx > 0 {
  126. writer.WriteString(",")
  127. }
  128. stmt.DB.Dialector.QuoteTo(writer, d)
  129. }
  130. writer.WriteByte(')')
  131. default:
  132. stmt.DB.Dialector.QuoteTo(writer, fmt.Sprint(field))
  133. }
  134. }
  135. // Quote returns quoted value
  136. func (stmt *Statement) Quote(field interface{}) string {
  137. var builder strings.Builder
  138. stmt.QuoteTo(&builder, field)
  139. return builder.String()
  140. }
  141. // AddVar add var
  142. func (stmt *Statement) AddVar(writer clause.Writer, vars ...interface{}) {
  143. for idx, v := range vars {
  144. if idx > 0 {
  145. writer.WriteByte(',')
  146. }
  147. switch v := v.(type) {
  148. case sql.NamedArg:
  149. stmt.Vars = append(stmt.Vars, v.Value)
  150. case clause.Column, clause.Table:
  151. stmt.QuoteTo(writer, v)
  152. case Valuer:
  153. stmt.AddVar(writer, v.GormValue(stmt.Context, stmt.DB))
  154. case clause.Expr:
  155. v.Build(stmt)
  156. case *clause.Expr:
  157. v.Build(stmt)
  158. case driver.Valuer:
  159. stmt.Vars = append(stmt.Vars, v)
  160. stmt.DB.Dialector.BindVarTo(writer, stmt, v)
  161. case []byte:
  162. stmt.Vars = append(stmt.Vars, v)
  163. stmt.DB.Dialector.BindVarTo(writer, stmt, v)
  164. case []interface{}:
  165. if len(v) > 0 {
  166. writer.WriteByte('(')
  167. stmt.AddVar(writer, v...)
  168. writer.WriteByte(')')
  169. } else {
  170. writer.WriteString("(NULL)")
  171. }
  172. case *DB:
  173. subdb := v.Session(&Session{Logger: logger.Discard, DryRun: true}).getInstance()
  174. if v.Statement.SQL.Len() > 0 {
  175. var (
  176. vars = subdb.Statement.Vars
  177. sql = v.Statement.SQL.String()
  178. )
  179. subdb.Statement.Vars = make([]interface{}, 0, len(vars))
  180. for _, vv := range vars {
  181. subdb.Statement.Vars = append(subdb.Statement.Vars, vv)
  182. bindvar := strings.Builder{}
  183. v.Dialector.BindVarTo(&bindvar, subdb.Statement, vv)
  184. sql = strings.Replace(sql, bindvar.String(), "?", 1)
  185. }
  186. subdb.Statement.SQL.Reset()
  187. subdb.Statement.Vars = stmt.Vars
  188. if strings.Contains(sql, "@") {
  189. clause.NamedExpr{SQL: sql, Vars: vars}.Build(subdb.Statement)
  190. } else {
  191. clause.Expr{SQL: sql, Vars: vars}.Build(subdb.Statement)
  192. }
  193. } else {
  194. subdb.Statement.Vars = append(stmt.Vars, subdb.Statement.Vars...)
  195. subdb.callbacks.Query().Execute(subdb)
  196. }
  197. writer.WriteString(subdb.Statement.SQL.String())
  198. stmt.Vars = subdb.Statement.Vars
  199. default:
  200. switch rv := reflect.ValueOf(v); rv.Kind() {
  201. case reflect.Slice, reflect.Array:
  202. if rv.Len() == 0 {
  203. writer.WriteString("(NULL)")
  204. } else {
  205. writer.WriteByte('(')
  206. for i := 0; i < rv.Len(); i++ {
  207. if i > 0 {
  208. writer.WriteByte(',')
  209. }
  210. stmt.AddVar(writer, rv.Index(i).Interface())
  211. }
  212. writer.WriteByte(')')
  213. }
  214. default:
  215. stmt.Vars = append(stmt.Vars, v)
  216. stmt.DB.Dialector.BindVarTo(writer, stmt, v)
  217. }
  218. }
  219. }
  220. }
  221. // AddClause add clause
  222. func (stmt *Statement) AddClause(v clause.Interface) {
  223. if optimizer, ok := v.(StatementModifier); ok {
  224. optimizer.ModifyStatement(stmt)
  225. } else {
  226. name := v.Name()
  227. c := stmt.Clauses[name]
  228. c.Name = name
  229. v.MergeClause(&c)
  230. stmt.Clauses[name] = c
  231. }
  232. }
  233. // AddClauseIfNotExists add clause if not exists
  234. func (stmt *Statement) AddClauseIfNotExists(v clause.Interface) {
  235. if c, ok := stmt.Clauses[v.Name()]; !ok || c.Expression == nil {
  236. stmt.AddClause(v)
  237. }
  238. }
  239. // BuildCondition build condition
  240. func (stmt *Statement) BuildCondition(query interface{}, args ...interface{}) []clause.Expression {
  241. if s, ok := query.(string); ok {
  242. // if it is a number, then treats it as primary key
  243. if _, err := strconv.Atoi(s); err != nil {
  244. if s == "" && len(args) == 0 {
  245. return nil
  246. } else if len(args) == 0 || (len(args) > 0 && strings.Contains(s, "?")) {
  247. // looks like a where condition
  248. return []clause.Expression{clause.Expr{SQL: s, Vars: args}}
  249. } else if len(args) > 0 && strings.Contains(s, "@") {
  250. // looks like a named query
  251. return []clause.Expression{clause.NamedExpr{SQL: s, Vars: args}}
  252. } else if len(args) == 1 {
  253. return []clause.Expression{clause.Eq{Column: s, Value: args[0]}}
  254. }
  255. }
  256. }
  257. conds := make([]clause.Expression, 0, 4)
  258. args = append([]interface{}{query}, args...)
  259. for idx, arg := range args {
  260. if valuer, ok := arg.(driver.Valuer); ok {
  261. arg, _ = valuer.Value()
  262. }
  263. switch v := arg.(type) {
  264. case clause.Expression:
  265. conds = append(conds, v)
  266. case *DB:
  267. if cs, ok := v.Statement.Clauses["WHERE"]; ok {
  268. if where, ok := cs.Expression.(clause.Where); ok {
  269. if len(where.Exprs) == 1 {
  270. if orConds, ok := where.Exprs[0].(clause.OrConditions); ok {
  271. where.Exprs[0] = clause.AndConditions(orConds)
  272. }
  273. }
  274. conds = append(conds, clause.And(where.Exprs...))
  275. } else if cs.Expression != nil {
  276. conds = append(conds, cs.Expression)
  277. }
  278. }
  279. case map[interface{}]interface{}:
  280. for i, j := range v {
  281. conds = append(conds, clause.Eq{Column: i, Value: j})
  282. }
  283. case map[string]string:
  284. var keys = make([]string, 0, len(v))
  285. for i := range v {
  286. keys = append(keys, i)
  287. }
  288. sort.Strings(keys)
  289. for _, key := range keys {
  290. conds = append(conds, clause.Eq{Column: key, Value: v[key]})
  291. }
  292. case map[string]interface{}:
  293. var keys = make([]string, 0, len(v))
  294. for i := range v {
  295. keys = append(keys, i)
  296. }
  297. sort.Strings(keys)
  298. for _, key := range keys {
  299. reflectValue := reflect.Indirect(reflect.ValueOf(v[key]))
  300. switch reflectValue.Kind() {
  301. case reflect.Slice, reflect.Array:
  302. if _, ok := v[key].(driver.Valuer); ok {
  303. conds = append(conds, clause.Eq{Column: key, Value: v[key]})
  304. } else if _, ok := v[key].(Valuer); ok {
  305. conds = append(conds, clause.Eq{Column: key, Value: v[key]})
  306. } else {
  307. // optimize reflect value length
  308. valueLen := reflectValue.Len()
  309. values := make([]interface{}, valueLen)
  310. for i := 0; i < valueLen; i++ {
  311. values[i] = reflectValue.Index(i).Interface()
  312. }
  313. conds = append(conds, clause.IN{Column: key, Values: values})
  314. }
  315. default:
  316. conds = append(conds, clause.Eq{Column: key, Value: v[key]})
  317. }
  318. }
  319. default:
  320. reflectValue := reflect.Indirect(reflect.ValueOf(arg))
  321. for reflectValue.Kind() == reflect.Ptr {
  322. reflectValue = reflectValue.Elem()
  323. }
  324. if s, err := schema.Parse(arg, stmt.DB.cacheStore, stmt.DB.NamingStrategy); err == nil {
  325. selectedColumns := map[string]bool{}
  326. if idx == 0 {
  327. for _, v := range args[1:] {
  328. if vs, ok := v.(string); ok {
  329. selectedColumns[vs] = true
  330. }
  331. }
  332. }
  333. restricted := len(selectedColumns) != 0
  334. switch reflectValue.Kind() {
  335. case reflect.Struct:
  336. for _, field := range s.Fields {
  337. selected := selectedColumns[field.DBName] || selectedColumns[field.Name]
  338. if selected || (!restricted && field.Readable) {
  339. if v, isZero := field.ValueOf(reflectValue); !isZero || selected {
  340. if field.DBName != "" {
  341. conds = append(conds, clause.Eq{Column: clause.Column{Table: clause.CurrentTable, Name: field.DBName}, Value: v})
  342. } else if field.DataType != "" {
  343. conds = append(conds, clause.Eq{Column: clause.Column{Table: clause.CurrentTable, Name: field.Name}, Value: v})
  344. }
  345. }
  346. }
  347. }
  348. case reflect.Slice, reflect.Array:
  349. for i := 0; i < reflectValue.Len(); i++ {
  350. for _, field := range s.Fields {
  351. selected := selectedColumns[field.DBName] || selectedColumns[field.Name]
  352. if selected || (!restricted && field.Readable) {
  353. if v, isZero := field.ValueOf(reflectValue.Index(i)); !isZero || selected {
  354. if field.DBName != "" {
  355. conds = append(conds, clause.Eq{Column: clause.Column{Table: clause.CurrentTable, Name: field.DBName}, Value: v})
  356. } else if field.DataType != "" {
  357. conds = append(conds, clause.Eq{Column: clause.Column{Table: clause.CurrentTable, Name: field.Name}, Value: v})
  358. }
  359. }
  360. }
  361. }
  362. }
  363. }
  364. if restricted {
  365. break
  366. }
  367. } else if !reflectValue.IsValid() {
  368. stmt.AddError(ErrInvalidData)
  369. } else if len(conds) == 0 {
  370. if len(args) == 1 {
  371. switch reflectValue.Kind() {
  372. case reflect.Slice, reflect.Array:
  373. // optimize reflect value length
  374. valueLen := reflectValue.Len()
  375. values := make([]interface{}, valueLen)
  376. for i := 0; i < valueLen; i++ {
  377. values[i] = reflectValue.Index(i).Interface()
  378. }
  379. if len(values) > 0 {
  380. conds = append(conds, clause.IN{Column: clause.PrimaryColumn, Values: values})
  381. }
  382. return conds
  383. }
  384. }
  385. conds = append(conds, clause.IN{Column: clause.PrimaryColumn, Values: args})
  386. }
  387. }
  388. }
  389. return conds
  390. }
  391. // Build build sql with clauses names
  392. func (stmt *Statement) Build(clauses ...string) {
  393. var firstClauseWritten bool
  394. for _, name := range clauses {
  395. if c, ok := stmt.Clauses[name]; ok {
  396. if firstClauseWritten {
  397. stmt.WriteByte(' ')
  398. }
  399. firstClauseWritten = true
  400. if b, ok := stmt.DB.ClauseBuilders[name]; ok {
  401. b(c, stmt)
  402. } else {
  403. c.Build(stmt)
  404. }
  405. }
  406. }
  407. }
  408. func (stmt *Statement) Parse(value interface{}) (err error) {
  409. if stmt.Schema, err = schema.Parse(value, stmt.DB.cacheStore, stmt.DB.NamingStrategy); err == nil && stmt.Table == "" {
  410. if tables := strings.Split(stmt.Schema.Table, "."); len(tables) == 2 {
  411. stmt.TableExpr = &clause.Expr{SQL: stmt.Quote(stmt.Schema.Table)}
  412. stmt.Table = tables[1]
  413. return
  414. }
  415. stmt.Table = stmt.Schema.Table
  416. }
  417. return err
  418. }
  419. func (stmt *Statement) clone() *Statement {
  420. newStmt := &Statement{
  421. TableExpr: stmt.TableExpr,
  422. Table: stmt.Table,
  423. Model: stmt.Model,
  424. Unscoped: stmt.Unscoped,
  425. Dest: stmt.Dest,
  426. ReflectValue: stmt.ReflectValue,
  427. Clauses: map[string]clause.Clause{},
  428. Distinct: stmt.Distinct,
  429. Selects: stmt.Selects,
  430. Omits: stmt.Omits,
  431. Preloads: map[string][]interface{}{},
  432. ConnPool: stmt.ConnPool,
  433. Schema: stmt.Schema,
  434. Context: stmt.Context,
  435. RaiseErrorOnNotFound: stmt.RaiseErrorOnNotFound,
  436. SkipHooks: stmt.SkipHooks,
  437. }
  438. if stmt.SQL.Len() > 0 {
  439. newStmt.SQL.WriteString(stmt.SQL.String())
  440. newStmt.Vars = make([]interface{}, 0, len(stmt.Vars))
  441. newStmt.Vars = append(newStmt.Vars, stmt.Vars...)
  442. }
  443. for k, c := range stmt.Clauses {
  444. newStmt.Clauses[k] = c
  445. }
  446. for k, p := range stmt.Preloads {
  447. newStmt.Preloads[k] = p
  448. }
  449. if len(stmt.Joins) > 0 {
  450. newStmt.Joins = make([]join, len(stmt.Joins))
  451. copy(newStmt.Joins, stmt.Joins)
  452. }
  453. if len(stmt.scopes) > 0 {
  454. newStmt.scopes = make([]func(*DB) *DB, len(stmt.scopes))
  455. copy(newStmt.scopes, stmt.scopes)
  456. }
  457. stmt.Settings.Range(func(k, v interface{}) bool {
  458. newStmt.Settings.Store(k, v)
  459. return true
  460. })
  461. return newStmt
  462. }
  463. // SetColumn set column's value
  464. // stmt.SetColumn("Name", "jinzhu") // Hooks Method
  465. // stmt.SetColumn("Name", "jinzhu", true) // Callbacks Method
  466. func (stmt *Statement) SetColumn(name string, value interface{}, fromCallbacks ...bool) {
  467. if v, ok := stmt.Dest.(map[string]interface{}); ok {
  468. v[name] = value
  469. } else if v, ok := stmt.Dest.([]map[string]interface{}); ok {
  470. for _, m := range v {
  471. m[name] = value
  472. }
  473. } else if stmt.Schema != nil {
  474. if field := stmt.Schema.LookUpField(name); field != nil {
  475. destValue := reflect.ValueOf(stmt.Dest)
  476. for destValue.Kind() == reflect.Ptr {
  477. destValue = destValue.Elem()
  478. }
  479. if stmt.ReflectValue != destValue {
  480. if !destValue.CanAddr() {
  481. destValueCanAddr := reflect.New(destValue.Type())
  482. destValueCanAddr.Elem().Set(destValue)
  483. stmt.Dest = destValueCanAddr.Interface()
  484. destValue = destValueCanAddr.Elem()
  485. }
  486. switch destValue.Kind() {
  487. case reflect.Struct:
  488. field.Set(destValue, value)
  489. default:
  490. stmt.AddError(ErrInvalidData)
  491. }
  492. }
  493. switch stmt.ReflectValue.Kind() {
  494. case reflect.Slice, reflect.Array:
  495. if len(fromCallbacks) > 0 {
  496. for i := 0; i < stmt.ReflectValue.Len(); i++ {
  497. field.Set(stmt.ReflectValue.Index(i), value)
  498. }
  499. } else {
  500. field.Set(stmt.ReflectValue.Index(stmt.CurDestIndex), value)
  501. }
  502. case reflect.Struct:
  503. if !stmt.ReflectValue.CanAddr() {
  504. stmt.AddError(ErrInvalidValue)
  505. return
  506. }
  507. field.Set(stmt.ReflectValue, value)
  508. }
  509. } else {
  510. stmt.AddError(ErrInvalidField)
  511. }
  512. } else {
  513. stmt.AddError(ErrInvalidField)
  514. }
  515. }
  516. // Changed check model changed or not when updating
  517. func (stmt *Statement) Changed(fields ...string) bool {
  518. modelValue := stmt.ReflectValue
  519. switch modelValue.Kind() {
  520. case reflect.Slice, reflect.Array:
  521. modelValue = stmt.ReflectValue.Index(stmt.CurDestIndex)
  522. }
  523. selectColumns, restricted := stmt.SelectAndOmitColumns(false, true)
  524. changed := func(field *schema.Field) bool {
  525. fieldValue, _ := field.ValueOf(modelValue)
  526. if v, ok := selectColumns[field.DBName]; (ok && v) || (!ok && !restricted) {
  527. if v, ok := stmt.Dest.(map[string]interface{}); ok {
  528. if fv, ok := v[field.Name]; ok {
  529. return !utils.AssertEqual(fv, fieldValue)
  530. } else if fv, ok := v[field.DBName]; ok {
  531. return !utils.AssertEqual(fv, fieldValue)
  532. }
  533. } else {
  534. destValue := reflect.ValueOf(stmt.Dest)
  535. for destValue.Kind() == reflect.Ptr {
  536. destValue = destValue.Elem()
  537. }
  538. changedValue, zero := field.ValueOf(destValue)
  539. return !zero && !utils.AssertEqual(changedValue, fieldValue)
  540. }
  541. }
  542. return false
  543. }
  544. if len(fields) == 0 {
  545. for _, field := range stmt.Schema.FieldsByDBName {
  546. if changed(field) {
  547. return true
  548. }
  549. }
  550. } else {
  551. for _, name := range fields {
  552. if field := stmt.Schema.LookUpField(name); field != nil {
  553. if changed(field) {
  554. return true
  555. }
  556. }
  557. }
  558. }
  559. return false
  560. }
  561. // SelectAndOmitColumns get select and omit columns, select -> true, omit -> false
  562. func (stmt *Statement) SelectAndOmitColumns(requireCreate, requireUpdate bool) (map[string]bool, bool) {
  563. results := map[string]bool{}
  564. notRestricted := false
  565. // select columns
  566. for _, column := range stmt.Selects {
  567. if stmt.Schema == nil {
  568. results[column] = true
  569. } else if column == "*" {
  570. notRestricted = true
  571. for _, dbName := range stmt.Schema.DBNames {
  572. results[dbName] = true
  573. }
  574. } else if column == clause.Associations {
  575. for _, rel := range stmt.Schema.Relationships.Relations {
  576. results[rel.Name] = true
  577. }
  578. } else if field := stmt.Schema.LookUpField(column); field != nil && field.DBName != "" {
  579. results[field.DBName] = true
  580. } else {
  581. results[column] = true
  582. }
  583. }
  584. // omit columns
  585. for _, omit := range stmt.Omits {
  586. if stmt.Schema == nil {
  587. results[omit] = false
  588. } else if omit == clause.Associations {
  589. for _, rel := range stmt.Schema.Relationships.Relations {
  590. results[rel.Name] = false
  591. }
  592. } else if field := stmt.Schema.LookUpField(omit); field != nil && field.DBName != "" {
  593. results[field.DBName] = false
  594. } else {
  595. results[omit] = false
  596. }
  597. }
  598. if stmt.Schema != nil {
  599. for _, field := range stmt.Schema.FieldsByName {
  600. name := field.DBName
  601. if name == "" {
  602. name = field.Name
  603. }
  604. if requireCreate && !field.Creatable {
  605. results[name] = false
  606. } else if requireUpdate && !field.Updatable {
  607. results[name] = false
  608. }
  609. }
  610. }
  611. return results, !notRestricted && len(stmt.Selects) > 0
  612. }