@@ -61,7 +61,6 @@ func (n *EvalReadDataPlan) Eval(ctx EvalContext) (interface{}, error) {
6161 }
6262
6363 configKnown := configVal .IsWhollyKnown ()
64- proposedNewVal := objchange .PlannedDataResourceObject (schema , configVal )
6564 // If our configuration contains any unknown values, or we depend on any
6665 // unknown values then we must defer the read to the apply phase by
6766 // producing a "Read" change for this resource, and a placeholder value for
@@ -73,6 +72,8 @@ func (n *EvalReadDataPlan) Eval(ctx EvalContext) (interface{}, error) {
7372 log .Printf ("[TRACE] EvalReadDataPlan: %s configuration not fully known yet, so deferring to apply phase" , absAddr )
7473 }
7574
75+ proposedNewVal := objchange .PlannedDataResourceObject (schema , configVal )
76+
7677 err := ctx .Hook (func (h Hook ) (HookAction , error ) {
7778 return h .PreDiff (absAddr , states .CurrentGen , priorVal , proposedNewVal )
7879 })
@@ -101,42 +102,43 @@ func (n *EvalReadDataPlan) Eval(ctx EvalContext) (interface{}, error) {
101102 return nil , diags .ErrWithWarnings ()
102103 }
103104
105+ // If we have a stored state we may not need to re-read the data source.
106+ // Check the config against the state to see if there are any difference.
107+ if ! priorVal .IsNull () {
108+ // Applying the configuration to the prior state lets us see if there
109+ // are any differences.
110+ proposed := objchange .ProposedNewObject (schema , priorVal , configVal )
111+ if proposed .Equals (priorVal ).True () {
112+ log .Printf ("[TRACE] EvalReadDataPlan: %s no change detected, using existing state" , absAddr )
113+ // state looks up to date, and must have been read during refresh
114+ return nil , diags .ErrWithWarnings ()
115+ }
116+ }
117+
104118 newVal , readDiags := n .readDataSource (ctx , configVal )
105119 diags = diags .Append (readDiags )
106120 if diags .HasErrors () {
107121 return nil , diags .ErrWithWarnings ()
108122 }
109123
110- action := plans .NoOp
111- if ! newVal .IsNull () && newVal .IsKnown () && newVal .Equals (priorVal ).False () {
112- // since a data source is read-only, update here only means that we
113- // need to update the state.
114- action = plans .Update
115- }
116-
117124 // Produce a change regardless of the outcome.
118125 change := & plans.ResourceInstanceChange {
119126 Addr : absAddr ,
120127 ProviderAddr : n .ProviderAddr ,
121128 Change : plans.Change {
122- Action : action ,
129+ Action : plans . Update ,
123130 Before : priorVal ,
124131 After : newVal ,
125132 },
126133 }
127134
128- status := states .ObjectReady
129- if action == plans .Update {
130- status = states .ObjectPlanned
131- }
132-
133135 outputState := & states.ResourceInstanceObject {
134136 Value : newVal ,
135- Status : status ,
137+ Status : states . ObjectPlanned ,
136138 }
137139
138140 if err := ctx .Hook (func (h Hook ) (HookAction , error ) {
139- return h .PostDiff (absAddr , states .CurrentGen , action , priorVal , newVal )
141+ return h .PostDiff (absAddr , states .CurrentGen , plans . Update , priorVal , newVal )
140142 }); err != nil {
141143 return nil , err
142144 }
0 commit comments