@@ -41,6 +41,7 @@ type ExecutableQuery interface {
4141 Keyspace () string
4242 Table () string
4343 IsIdempotent () bool
44+ GetHost () * HostInfo
4445
4546 withContext (context.Context ) ExecutableQuery
4647
@@ -83,12 +84,27 @@ func (q *queryExecutor) speculate(ctx context.Context, qry ExecutableQuery, sp S
8384}
8485
8586func (q * queryExecutor ) executeQuery (qry ExecutableQuery ) (* Iter , error ) {
86- hostIter := q .policy .Pick (qry )
87+ var hostIter NextHost
88+
89+ // checking if the host is specified for the query,
90+ // if it is, the query should be executed at the specified host
91+ host := qry .GetHost ()
92+ if host != nil {
93+ hostIter = func () SelectedHost {
94+ return (* selectedHost )(host )
95+ }
96+ }
97+
98+ // if host is not specified for the query,
99+ // then a host will be picked by HostSelectionPolicy
100+ if hostIter == nil {
101+ hostIter = q .policy .Pick (qry )
102+ }
87103
88104 // check if the query is not marked as idempotent, if
89105 // it is, we force the policy to NonSpeculative
90106 sp := qry .speculativeExecutionPolicy ()
91- if ! qry .IsIdempotent () || sp .Attempts () == 0 {
107+ if host != nil || ! qry .IsIdempotent () || sp .Attempts () == 0 {
92108 return q .do (qry .Context (), qry , hostIter ), nil
93109 }
94110
@@ -129,12 +145,17 @@ func (q *queryExecutor) executeQuery(qry ExecutableQuery) (*Iter, error) {
129145func (q * queryExecutor ) do (ctx context.Context , qry ExecutableQuery , hostIter NextHost ) * Iter {
130146 selectedHost := hostIter ()
131147 rt := qry .retryPolicy ()
148+ specifiedHost := qry .GetHost ()
132149
133150 var lastErr error
134151 var iter * Iter
135152 for selectedHost != nil {
136153 host := selectedHost .Info ()
137- if host == nil || ! host .IsUp () {
154+ if specifiedHost != nil && host != nil && ! host .IsUp () {
155+ return & Iter {err : ErrNoConnections }
156+ }
157+
158+ if (host == nil || ! host .IsUp ()) && specifiedHost == nil {
138159 selectedHost = hostIter ()
139160 continue
140161 }
@@ -166,7 +187,9 @@ func (q *queryExecutor) do(ctx context.Context, qry ExecutableQuery, hostIter Ne
166187
167188 // Exit if the query was successful
168189 // or query is not idempotent or no retry policy defined
169- if iter .err == nil || ! qry .IsIdempotent () || rt == nil {
190+ // Also, if there is specified host for the query to be executed on
191+ // and query execution is failed we should exit
192+ if iter .err == nil || specifiedHost != nil || ! qry .IsIdempotent () || rt == nil {
170193 return iter
171194 }
172195
0 commit comments