Skip to content

Commit 3fce598

Browse files
kyleconroyclaude
andcommitted
Add CREATE ENDPOINT statement support with all protocol/payload options
- Add IPv6 address support for LISTENER_IP (string literal in parentheses) - Add HTTP protocol options: PATH, AUTHENTICATION, PORTS, COMPRESSION, SITE, CLEAR_PORT, SSL_PORT, AUTH_REALM, DEFAULT_LOGON_DOMAIN - Add SOAP payload options: WEBMETHOD (with namespace.alias syntax), BATCHES, SESSIONS, WSDL, LOGIN_TYPE, SESSION_TIMEOUT, DATABASE, NAMESPACE, SCHEMA, CHARACTER_SET, HEADER_LIMIT - Add SERVICE_BROKER/DATABASE_MIRRORING options: AUTHENTICATION (with various Windows/Certificate combinations), ENCRYPTION (with algorithm support), ROLE, MESSAGE_FORWARDING, MESSAGE_FORWARD_SIZE - Add new AST types: AuthenticationEndpointProtocolOption, PortsEndpointProtocolOption, CompressionEndpointProtocolOption, AuthenticationPayloadOption, EncryptionPayloadOption, RolePayloadOption, LiteralPayloadOption, SchemaPayloadOption, CharacterSetPayloadOption, SessionTimeoutPayloadOption, WsdlPayloadOption, LoginTypePayloadOption - Add SoapMethod.Namespace field for 'namespace'.'alias' webmethod syntax Enables: CreateEndpointStatementTests, Baselines90_CreateEndpointStatementTests Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 1133ab8 commit 3fce598

6 files changed

Lines changed: 806 additions & 92 deletions

File tree

ast/alter_simple_statements.go

Lines changed: 131 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -148,12 +148,40 @@ type ListenerIPEndpointProtocolOption struct {
148148
IsAll bool
149149
IPv4PartOne *IPv4
150150
IPv4PartTwo *IPv4
151+
IPv6 *StringLiteral
151152
Kind string // TcpListenerIP, HttpListenerIP, etc.
152153
}
153154

154155
func (l *ListenerIPEndpointProtocolOption) node() {}
155156
func (l *ListenerIPEndpointProtocolOption) endpointProtocolOption() {}
156157

158+
// AuthenticationEndpointProtocolOption represents HTTP authentication option.
159+
type AuthenticationEndpointProtocolOption struct {
160+
AuthenticationTypes string `json:"AuthenticationTypes,omitempty"` // Comma-separated list: Basic, Digest, Integrated, Ntlm, Kerberos
161+
Kind string `json:"Kind,omitempty"` // HttpAuthentication
162+
}
163+
164+
func (a *AuthenticationEndpointProtocolOption) node() {}
165+
func (a *AuthenticationEndpointProtocolOption) endpointProtocolOption() {}
166+
167+
// PortsEndpointProtocolOption represents HTTP ports option.
168+
type PortsEndpointProtocolOption struct {
169+
PortTypes string `json:"PortTypes,omitempty"` // Comma-separated list: Clear, Ssl
170+
Kind string `json:"Kind,omitempty"` // HttpPorts
171+
}
172+
173+
func (p *PortsEndpointProtocolOption) node() {}
174+
func (p *PortsEndpointProtocolOption) endpointProtocolOption() {}
175+
176+
// CompressionEndpointProtocolOption represents HTTP compression option.
177+
type CompressionEndpointProtocolOption struct {
178+
IsEnabled bool `json:"IsEnabled"`
179+
Kind string `json:"Kind,omitempty"` // HttpCompression
180+
}
181+
182+
func (c *CompressionEndpointProtocolOption) node() {}
183+
func (c *CompressionEndpointProtocolOption) endpointProtocolOption() {}
184+
157185
// PayloadOption is an interface for endpoint payload options.
158186
type PayloadOption interface {
159187
Node
@@ -162,17 +190,114 @@ type PayloadOption interface {
162190

163191
// SoapMethod represents a SOAP web method option.
164192
type SoapMethod struct {
165-
Alias *StringLiteral `json:"Alias,omitempty"`
166-
Action string `json:"Action,omitempty"` // Add, Alter, Drop
167-
Name *StringLiteral `json:"Name,omitempty"`
168-
Format string `json:"Format,omitempty"` // NotSpecified, AllResults, RowsetsOnly, None
169-
Schema string `json:"Schema,omitempty"` // NotSpecified, Default, None, Standard
170-
Kind string `json:"Kind,omitempty"` // None, WebMethod
193+
Alias *StringLiteral `json:"Alias,omitempty"`
194+
Namespace *StringLiteral `json:"Namespace,omitempty"`
195+
Action string `json:"Action,omitempty"` // None, Add, Alter, Drop
196+
Name *StringLiteral `json:"Name,omitempty"`
197+
Format string `json:"Format,omitempty"` // NotSpecified, AllResults, RowsetsOnly, None
198+
Schema string `json:"Schema,omitempty"` // NotSpecified, Default, None, Standard
199+
Kind string `json:"Kind,omitempty"` // None, WebMethod
171200
}
172201

173202
func (s *SoapMethod) node() {}
174203
func (s *SoapMethod) payloadOption() {}
175204

205+
// EnabledDisabledPayloadOption represents an enabled/disabled payload option like BATCHES, SESSIONS.
206+
type EnabledDisabledPayloadOption struct {
207+
IsEnabled bool `json:"IsEnabled"`
208+
Kind string `json:"Kind,omitempty"` // Batches, Sessions, MessageForwarding, etc.
209+
}
210+
211+
func (e *EnabledDisabledPayloadOption) node() {}
212+
func (e *EnabledDisabledPayloadOption) payloadOption() {}
213+
214+
// AuthenticationPayloadOption represents an authentication option for service_broker/database_mirroring.
215+
type AuthenticationPayloadOption struct {
216+
Protocol string `json:"Protocol,omitempty"` // Windows, WindowsNtlm, WindowsKerberos, WindowsNegotiate, Certificate
217+
Certificate *Identifier `json:"Certificate,omitempty"`
218+
TryCertificateFirst bool `json:"TryCertificateFirst"`
219+
Kind string `json:"Kind,omitempty"` // Authentication
220+
}
221+
222+
func (a *AuthenticationPayloadOption) node() {}
223+
func (a *AuthenticationPayloadOption) payloadOption() {}
224+
225+
// EncryptionPayloadOption represents an encryption option for service_broker/database_mirroring.
226+
type EncryptionPayloadOption struct {
227+
EncryptionSupport string `json:"EncryptionSupport,omitempty"` // Disabled, Supported, Required, NotSpecified
228+
AlgorithmPartOne string `json:"AlgorithmPartOne,omitempty"` // NotSpecified, Rc4, Aes
229+
AlgorithmPartTwo string `json:"AlgorithmPartTwo,omitempty"` // NotSpecified, Rc4, Aes
230+
Kind string `json:"Kind,omitempty"` // Encryption
231+
}
232+
233+
func (e *EncryptionPayloadOption) node() {}
234+
func (e *EncryptionPayloadOption) payloadOption() {}
235+
236+
// RolePayloadOption represents a role option for database_mirroring.
237+
type RolePayloadOption struct {
238+
Role string `json:"Role,omitempty"` // NotSpecified, All, Partner, Witness
239+
Kind string `json:"Kind,omitempty"` // Role
240+
}
241+
242+
func (r *RolePayloadOption) node() {}
243+
func (r *RolePayloadOption) payloadOption() {}
244+
245+
// LiteralPayloadOption represents a literal value payload option.
246+
type LiteralPayloadOption struct {
247+
Value ScalarExpression `json:"Value,omitempty"`
248+
Kind string `json:"Kind,omitempty"`
249+
}
250+
251+
func (l *LiteralPayloadOption) node() {}
252+
func (l *LiteralPayloadOption) payloadOption() {}
253+
254+
// SchemaPayloadOption represents a SCHEMA payload option for SOAP.
255+
type SchemaPayloadOption struct {
256+
IsStandard bool `json:"IsStandard"`
257+
Kind string `json:"Kind,omitempty"` // Schema
258+
}
259+
260+
func (s *SchemaPayloadOption) node() {}
261+
func (s *SchemaPayloadOption) payloadOption() {}
262+
263+
// CharacterSetPayloadOption represents a CHARACTER_SET payload option for SOAP.
264+
type CharacterSetPayloadOption struct {
265+
IsSql bool `json:"IsSql"`
266+
Kind string `json:"Kind,omitempty"` // CharacterSet
267+
}
268+
269+
func (c *CharacterSetPayloadOption) node() {}
270+
func (c *CharacterSetPayloadOption) payloadOption() {}
271+
272+
// SessionTimeoutPayloadOption represents a SESSION_TIMEOUT payload option for SOAP.
273+
type SessionTimeoutPayloadOption struct {
274+
Timeout *IntegerLiteral `json:"Timeout,omitempty"`
275+
IsNever bool `json:"IsNever"`
276+
Kind string `json:"Kind,omitempty"` // SessionTimeout
277+
}
278+
279+
func (s *SessionTimeoutPayloadOption) node() {}
280+
func (s *SessionTimeoutPayloadOption) payloadOption() {}
281+
282+
// WsdlPayloadOption represents a WSDL payload option for SOAP.
283+
type WsdlPayloadOption struct {
284+
Value ScalarExpression `json:"Value,omitempty"`
285+
IsNone bool `json:"IsNone"`
286+
Kind string `json:"Kind,omitempty"` // Wsdl
287+
}
288+
289+
func (w *WsdlPayloadOption) node() {}
290+
func (w *WsdlPayloadOption) payloadOption() {}
291+
292+
// LoginTypePayloadOption represents a LOGIN_TYPE payload option for SOAP.
293+
type LoginTypePayloadOption struct {
294+
IsWindows bool `json:"IsWindows"`
295+
Kind string `json:"Kind,omitempty"` // LoginType
296+
}
297+
298+
func (l *LoginTypePayloadOption) node() {}
299+
func (l *LoginTypePayloadOption) payloadOption() {}
300+
176301
// AlterServiceStatement represents an ALTER SERVICE statement.
177302
type AlterServiceStatement struct {
178303
Name *Identifier `json:"Name,omitempty"`

parser/marshal.go

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18030,6 +18030,36 @@ func endpointProtocolOptionToJSON(opt ast.EndpointProtocolOption) jsonNode {
1803018030
if o.IPv4PartTwo != nil {
1803118031
node["IPv4PartTwo"] = ipv4ToJSON(o.IPv4PartTwo)
1803218032
}
18033+
if o.IPv6 != nil {
18034+
node["IPv6"] = scalarExpressionToJSON(o.IPv6)
18035+
}
18036+
if o.Kind != "" {
18037+
node["Kind"] = o.Kind
18038+
}
18039+
return node
18040+
case *ast.AuthenticationEndpointProtocolOption:
18041+
node := jsonNode{
18042+
"$type": "AuthenticationEndpointProtocolOption",
18043+
"AuthenticationTypes": o.AuthenticationTypes,
18044+
}
18045+
if o.Kind != "" {
18046+
node["Kind"] = o.Kind
18047+
}
18048+
return node
18049+
case *ast.PortsEndpointProtocolOption:
18050+
node := jsonNode{
18051+
"$type": "PortsEndpointProtocolOption",
18052+
"PortTypes": o.PortTypes,
18053+
}
18054+
if o.Kind != "" {
18055+
node["Kind"] = o.Kind
18056+
}
18057+
return node
18058+
case *ast.CompressionEndpointProtocolOption:
18059+
node := jsonNode{
18060+
"$type": "CompressionEndpointProtocolOption",
18061+
"IsEnabled": o.IsEnabled,
18062+
}
1803318063
if o.Kind != "" {
1803418064
node["Kind"] = o.Kind
1803518065
}
@@ -18067,6 +18097,9 @@ func payloadOptionToJSON(opt ast.PayloadOption) jsonNode {
1806718097
if o.Alias != nil {
1806818098
node["Alias"] = stringLiteralToJSON(o.Alias)
1806918099
}
18100+
if o.Namespace != nil {
18101+
node["Namespace"] = stringLiteralToJSON(o.Namespace)
18102+
}
1807018103
if o.Action != "" {
1807118104
node["Action"] = o.Action
1807218105
}
@@ -18083,6 +18116,110 @@ func payloadOptionToJSON(opt ast.PayloadOption) jsonNode {
1808318116
node["Kind"] = o.Kind
1808418117
}
1808518118
return node
18119+
case *ast.EnabledDisabledPayloadOption:
18120+
node := jsonNode{
18121+
"$type": "EnabledDisabledPayloadOption",
18122+
"IsEnabled": o.IsEnabled,
18123+
}
18124+
if o.Kind != "" {
18125+
node["Kind"] = o.Kind
18126+
}
18127+
return node
18128+
case *ast.AuthenticationPayloadOption:
18129+
node := jsonNode{
18130+
"$type": "AuthenticationPayloadOption",
18131+
"Protocol": o.Protocol,
18132+
"TryCertificateFirst": o.TryCertificateFirst,
18133+
}
18134+
if o.Certificate != nil {
18135+
node["Certificate"] = identifierToJSON(o.Certificate)
18136+
}
18137+
if o.Kind != "" {
18138+
node["Kind"] = o.Kind
18139+
}
18140+
return node
18141+
case *ast.EncryptionPayloadOption:
18142+
node := jsonNode{
18143+
"$type": "EncryptionPayloadOption",
18144+
"EncryptionSupport": o.EncryptionSupport,
18145+
"AlgorithmPartOne": o.AlgorithmPartOne,
18146+
"AlgorithmPartTwo": o.AlgorithmPartTwo,
18147+
}
18148+
if o.Kind != "" {
18149+
node["Kind"] = o.Kind
18150+
}
18151+
return node
18152+
case *ast.RolePayloadOption:
18153+
node := jsonNode{
18154+
"$type": "RolePayloadOption",
18155+
"Role": o.Role,
18156+
}
18157+
if o.Kind != "" {
18158+
node["Kind"] = o.Kind
18159+
}
18160+
return node
18161+
case *ast.LiteralPayloadOption:
18162+
node := jsonNode{
18163+
"$type": "LiteralPayloadOption",
18164+
}
18165+
if o.Value != nil {
18166+
node["Value"] = scalarExpressionToJSON(o.Value)
18167+
}
18168+
if o.Kind != "" {
18169+
node["Kind"] = o.Kind
18170+
}
18171+
return node
18172+
case *ast.SchemaPayloadOption:
18173+
node := jsonNode{
18174+
"$type": "SchemaPayloadOption",
18175+
"IsStandard": o.IsStandard,
18176+
}
18177+
if o.Kind != "" {
18178+
node["Kind"] = o.Kind
18179+
}
18180+
return node
18181+
case *ast.CharacterSetPayloadOption:
18182+
node := jsonNode{
18183+
"$type": "CharacterSetPayloadOption",
18184+
"IsSql": o.IsSql,
18185+
}
18186+
if o.Kind != "" {
18187+
node["Kind"] = o.Kind
18188+
}
18189+
return node
18190+
case *ast.SessionTimeoutPayloadOption:
18191+
node := jsonNode{
18192+
"$type": "SessionTimeoutPayloadOption",
18193+
"IsNever": o.IsNever,
18194+
}
18195+
if o.Timeout != nil {
18196+
node["Timeout"] = scalarExpressionToJSON(o.Timeout)
18197+
}
18198+
if o.Kind != "" {
18199+
node["Kind"] = o.Kind
18200+
}
18201+
return node
18202+
case *ast.WsdlPayloadOption:
18203+
node := jsonNode{
18204+
"$type": "WsdlPayloadOption",
18205+
"IsNone": o.IsNone,
18206+
}
18207+
if o.Value != nil {
18208+
node["Value"] = scalarExpressionToJSON(o.Value)
18209+
}
18210+
if o.Kind != "" {
18211+
node["Kind"] = o.Kind
18212+
}
18213+
return node
18214+
case *ast.LoginTypePayloadOption:
18215+
node := jsonNode{
18216+
"$type": "LoginTypePayloadOption",
18217+
"IsWindows": o.IsWindows,
18218+
}
18219+
if o.Kind != "" {
18220+
node["Kind"] = o.Kind
18221+
}
18222+
return node
1808618223
default:
1808718224
return jsonNode{"$type": "UnknownPayloadOption"}
1808818225
}

0 commit comments

Comments
 (0)