@@ -130,7 +130,11 @@ public void execute(SqlCreateView create, CalcitePrepare.Context context) {
130130 throw new DdlException (create ,
131131 "View " + pair .right + " already exists. Use CREATE OR REPLACE to update." );
132132 }
133- pair .left .removeFunction (pair .right );
133+ // Apply the in-memory schema change whenever the mode persists it (CREATE/UPDATE deploy
134+ // for real; VALIDATE keeps it in-memory only). SPECIFY render is not reached here.
135+ if (mode .persistsSchema ()) {
136+ pair .left .removeFunction (pair .right );
137+ }
134138 }
135139 }
136140
@@ -152,14 +156,20 @@ public void execute(SqlCreateView create, CalcitePrepare.Context context) {
152156 deployers = DeploymentService .deployers (view , connection );
153157 ValidationService .validateOrThrow (deployers , connection );
154158 logger .info ("Validated view {}" , viewName );
159+ // CREATE→create, UPDATE→update, VALIDATE (dry-run)→deploy nothing. In every case the
160+ // in-memory view is registered (VALIDATE persists it without deploying), so a later
161+ // statement in the same script sees it.
155162 if (mode == HoptimatorDdlUtils .DdlMode .UPDATE ) {
156163 logger .info ("Deploying update view {}" , viewName );
157- DeploymentService .update (deployers );
158- } else {
164+ } else if (mode == HoptimatorDdlUtils .DdlMode .CREATE ) {
159165 logger .info ("Deploying create view {}" , viewName );
160- DeploymentService .create (deployers );
166+ } else {
167+ logger .info ("Validating (dry-run) view {}; skipping deployment" , viewName );
168+ }
169+ mode .executeDeployers (deployers , connection );
170+ if (mode != HoptimatorDdlUtils .DdlMode .VALIDATE ) {
171+ logger .info ("Deployed view {}" , viewName );
161172 }
162- logger .info ("Deployed view {}" , viewName );
163173 schemaPlus .add (viewName , viewTable );
164174 logger .info ("Added view {} to schema {}" , viewName , schemaPlus .getName ());
165175 } catch (SQLException | RuntimeException e ) {
@@ -243,12 +253,17 @@ public void execute(SqlCreateTrigger create, CalcitePrepare.Context context) {
243253 HoptimatorDdlUtils .DdlMode mode = HoptimatorDdlUtils .effectiveMode (create .getReplace (), connection );
244254 if (mode == HoptimatorDdlUtils .DdlMode .UPDATE ) {
245255 logger .info ("Updating trigger {}" , name );
246- DeploymentService .update (deployers );
247- } else {
256+ } else if (mode == HoptimatorDdlUtils .DdlMode .CREATE ) {
248257 logger .info ("Creating trigger {}" , name );
249- DeploymentService .create (deployers );
258+ } else {
259+ logger .info ("Validating (dry-run) trigger {}; skipping deployment" , name );
260+ }
261+ // CREATE→create, UPDATE→update, VALIDATE (dry-run)→no-op. Triggers are not part of the
262+ // Calcite schema, so there is no in-memory state to persist.
263+ mode .executeDeployers (deployers , connection );
264+ if (mode != HoptimatorDdlUtils .DdlMode .VALIDATE ) {
265+ logger .info ("Deployed trigger {}" , name );
250266 }
251- logger .info ("Deployed trigger {}" , name );
252267 logger .info ("CREATE TRIGGER {} completed" , name );
253268 } catch (Exception e ) {
254269 if (deployers != null ) {
@@ -336,7 +351,11 @@ public void execute(SqlFireTrigger fire, CalcitePrepare.Context context) {
336351 try {
337352 logger .info ("Firing trigger {} with {} option(s)" , name , options .size () - 1 );
338353 deployers = DeploymentService .deployers (trigger , connection );
339- DeploymentService .update (deployers );
354+ if (HoptimatorDdlUtils .isValidateMode (connection )) {
355+ logger .info ("Validated FIRE TRIGGER (dry-run) {}; skipping deployment" , name );
356+ } else {
357+ DeploymentService .update (deployers );
358+ }
340359 logger .info ("FIRE TRIGGER {} completed" , name );
341360 } catch (Exception e ) {
342361 if (deployers != null ) {
@@ -366,8 +385,12 @@ public void execute(SqlDropTrigger drop, CalcitePrepare.Context context) {
366385 try {
367386 logger .info ("Deleting trigger {}" , name );
368387 deployers = DeploymentService .deployers (trigger , connection );
369- DeploymentService .delete (deployers );
370- logger .info ("Deleted trigger {}" , name );
388+ if (HoptimatorDdlUtils .isValidateMode (connection )) {
389+ logger .info ("Validated DROP TRIGGER (dry-run) {}; skipping deletion" , name );
390+ } else {
391+ DeploymentService .delete (deployers );
392+ logger .info ("Deleted trigger {}" , name );
393+ }
371394 logger .info ("DROP TRIGGER {} completed" , name );
372395 } catch (Exception e ) {
373396 if (deployers != null ) {
@@ -403,7 +426,11 @@ private void updateTriggerPausedState(SqlNode sqlNode, SqlIdentifier triggerName
403426 try {
404427 logger .info ("Updating trigger {} with paused state: {}" , name , paused );
405428 deployers = DeploymentService .deployers (trigger , connection );
406- DeploymentService .update (deployers );
429+ if (HoptimatorDdlUtils .isValidateMode (connection )) {
430+ logger .info ("Validated paused-state update (dry-run) for trigger {}; skipping deployment" , name );
431+ } else {
432+ DeploymentService .update (deployers );
433+ }
407434 logger .info ("Successfully updated trigger {} with paused state: {}" , name , paused );
408435 } catch (Exception e ) {
409436 if (deployers != null ) {
@@ -450,6 +477,7 @@ public void execute(SqlDropObject drop, CalcitePrepare.Context context) {
450477 tablePath .add (tableName );
451478
452479 Collection <Deployer > deployers = null ;
480+ final boolean dryRun = HoptimatorDdlUtils .isValidateMode (connection );
453481 try {
454482 if (table instanceof MaterializedViewTable ) {
455483 if (!(drop instanceof SqlDropMaterializedView )) {
@@ -459,8 +487,14 @@ public void execute(SqlDropObject drop, CalcitePrepare.Context context) {
459487 MaterializedViewTable materializedViewTable = (MaterializedViewTable ) table ;
460488 View view = new View (tablePath , materializedViewTable .viewSql ());
461489 deployers = DeploymentService .deployers (view , connection );
462- logger .info ("Deleting materialized view {}" , tableName );
463- DeploymentService .delete (deployers );
490+ if (dryRun ) {
491+ logger .info ("Validated DROP (dry-run) for materialized view {}; skipping deletion" , tableName );
492+ } else {
493+ logger .info ("Deleting materialized view {}" , tableName );
494+ DeploymentService .delete (deployers );
495+ }
496+ // Always evolve the in-memory schema — even in a dry-run, dropping the view must make a
497+ // subsequent reference to it fail validation, regardless of whether a real object existed.
464498 schemaPlus .removeTable (tableName );
465499 logger .info ("Removed materialized table {} from schema {}" , tableName , schemaPlus .getName ());
466500 } else if (table instanceof ViewTable ) {
@@ -471,8 +505,12 @@ public void execute(SqlDropObject drop, CalcitePrepare.Context context) {
471505 ViewTable viewTable = (ViewTable ) table ;
472506 View view = new View (tablePath , viewTable .getViewSql ());
473507 deployers = DeploymentService .deployers (view , connection );
474- logger .info ("Deleting view {}" , tableName );
475- DeploymentService .delete (deployers );
508+ if (dryRun ) {
509+ logger .info ("Validated DROP (dry-run) for view {}; skipping deletion" , tableName );
510+ } else {
511+ logger .info ("Deleting view {}" , tableName );
512+ DeploymentService .delete (deployers );
513+ }
476514 schemaPlus .removeTable (tableName );
477515 logger .info ("Removed view {} from schema {}" , tableName , schemaPlus .getName ());
478516 } else if (table instanceof HoptimatorJdbcTable || table instanceof TemporaryTable ) {
@@ -491,11 +529,15 @@ public void execute(SqlDropObject drop, CalcitePrepare.Context context) {
491529 }
492530 // Pre-delete dependency guard. PendingDelete is the explicit "delete intent" signal
493531 // — only validators that key off it (the K8s dep checker) fire here. The check throws
494- // before any deployer-level state change.
532+ // before any deployer-level state change. This validation runs in dry-run too.
495533 ValidationService .validateOrThrow (new PendingDelete <>(source ), connection );
496534 deployers = DeploymentService .deployers (source , connection );
497- logger .info ("Deleting table {}" , tableName );
498- DeploymentService .delete (deployers );
535+ if (dryRun ) {
536+ logger .info ("Validated DROP (dry-run) for table {}; skipping deletion" , tableName );
537+ } else {
538+ logger .info ("Deleting table {}" , tableName );
539+ DeploymentService .delete (deployers );
540+ }
499541 schemaPlus .removeTable (tableName );
500542 logger .info ("Removed table {} from schema {}" , tableName , schemaPlus .getName ());
501543 } else {
0 commit comments