Skip to content

Commit a7689ef

Browse files
authored
internal/dinosql: Quote reserved keywords (#205)
1 parent 3eacb36 commit a7689ef

File tree

3 files changed

+127
-0
lines changed

3 files changed

+127
-0
lines changed

internal/dinosql/parser.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -545,6 +545,9 @@ func expandStmt(c core.Catalog, raw nodes.RawStmt, node nodes.Node) ([]edit, err
545545
if scope != "" {
546546
cname = scope + "." + cname
547547
}
548+
if postgres.IsReservedKeyword(cname) {
549+
cname = "\"" + cname + "\""
550+
}
548551
cols = append(cols, cname)
549552
}
550553
}

internal/dinosql/query_test.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -813,6 +813,19 @@ func TestQueries(t *testing.T) {
813813
SQL: "SELECT a, b, c, d FROM foo, bar",
814814
},
815815
},
816+
{
817+
"star-expansion-reserved",
818+
`
819+
CREATE TABLE foo ("group" text);
820+
SELECT * FROM foo;
821+
`,
822+
Query{
823+
Columns: []core.Column{
824+
{Name: "group", DataType: "text", Table: public("foo")},
825+
},
826+
SQL: "SELECT \"group\" FROM foo",
827+
},
828+
},
816829
{
817830
"datetimes",
818831
`

internal/postgres/types.go

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package postgres
22

3+
import "strings"
4+
35
func IsComparisonOperator(s string) bool {
46
switch s {
57
case ">":
@@ -39,3 +41,112 @@ func IsMathematicalOperator(s string) bool {
3941
}
4042
return true
4143
}
44+
45+
// https://www.postgresql.org/docs/current/sql-keywords-appendix.html
46+
func IsReservedKeyword(s string) bool {
47+
switch strings.ToLower(s) {
48+
case "all":
49+
case "analyse":
50+
case "analyze":
51+
case "and":
52+
case "any":
53+
case "array":
54+
case "as":
55+
case "asc":
56+
case "asymmetric":
57+
case "authorization":
58+
case "binary":
59+
case "both":
60+
case "case":
61+
case "cast":
62+
case "check":
63+
case "collate":
64+
case "collation":
65+
case "column":
66+
case "concurrently":
67+
case "constraint":
68+
case "create":
69+
case "cross":
70+
case "current_catalog":
71+
case "current_date":
72+
case "current_role":
73+
case "current_schema":
74+
case "current_time":
75+
case "current_timestamp":
76+
case "current_user":
77+
case "default":
78+
case "deferrable":
79+
case "desc":
80+
case "distinct":
81+
case "do":
82+
case "else":
83+
case "end":
84+
case "except":
85+
case "false":
86+
case "fetch":
87+
case "for":
88+
case "foreign":
89+
case "freeze":
90+
case "from":
91+
case "full":
92+
case "grant":
93+
case "group":
94+
case "having":
95+
case "ilike":
96+
case "in":
97+
case "initially":
98+
case "inner":
99+
case "intersect":
100+
case "into":
101+
case "is":
102+
case "isnull":
103+
case "join":
104+
case "lateral":
105+
case "leading":
106+
case "left":
107+
case "like":
108+
case "limit":
109+
case "localtime":
110+
case "localtimestamp":
111+
case "natural":
112+
case "not":
113+
case "notnull":
114+
case "null":
115+
case "offset":
116+
case "on":
117+
case "only":
118+
case "or":
119+
case "order":
120+
case "outer":
121+
case "overlaps":
122+
case "placing":
123+
case "primary":
124+
case "references":
125+
case "returning":
126+
case "right":
127+
case "select":
128+
case "session_user":
129+
case "similar":
130+
case "some":
131+
case "symmetric":
132+
case "table":
133+
case "tablesample":
134+
case "then":
135+
case "to":
136+
case "trailing":
137+
case "true":
138+
case "union":
139+
case "unique":
140+
case "user":
141+
case "using":
142+
case "variadic":
143+
case "verbose":
144+
case "when":
145+
case "where":
146+
case "window":
147+
case "with":
148+
default:
149+
return false
150+
}
151+
return true
152+
}

0 commit comments

Comments
 (0)