@@ -9285,6 +9285,21 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
9285
9285
HeapTuple depTup ;
9286
9286
ObjectAddress address ;
9287
9287
9288
+ /*
9289
+ * Clear all the missing values if we're rewriting the table, since this
9290
+ * renders them pointless.
9291
+ */
9292
+ if (tab -> rewrite )
9293
+ {
9294
+ Relation newrel ;
9295
+
9296
+ newrel = heap_open (RelationGetRelid (rel ), NoLock );
9297
+ RelationClearMissing (newrel );
9298
+ relation_close (newrel , NoLock );
9299
+ /* make sure we don't conflict with later attribute modifications */
9300
+ CommandCounterIncrement ();
9301
+ }
9302
+
9288
9303
attrelation = heap_open (AttributeRelationId , RowExclusiveLock );
9289
9304
9290
9305
/* Look up the target column */
@@ -9601,7 +9616,69 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
9601
9616
/*
9602
9617
* Here we go --- change the recorded column type and collation. (Note
9603
9618
* heapTup is a copy of the syscache entry, so okay to scribble on.)
9619
+ * First fix up the missing value if any.
9604
9620
*/
9621
+ if (attTup -> atthasmissing )
9622
+ {
9623
+ Datum missingval ;
9624
+ bool missingNull ;
9625
+
9626
+ /* if rewrite is true the missing value should already be cleared */
9627
+ Assert (tab -> rewrite == 0 );
9628
+
9629
+ /* Get the missing value datum */
9630
+ missingval = heap_getattr (heapTup ,
9631
+ Anum_pg_attribute_attmissingval ,
9632
+ attrelation -> rd_att ,
9633
+ & missingNull );
9634
+
9635
+ /* if it's a null array there is nothing to do */
9636
+
9637
+ if (! missingNull )
9638
+ {
9639
+ /*
9640
+ * Get the datum out of the array and repack it in a new array
9641
+ * built with the new type data. We assume that since the table
9642
+ * doesn't need rewriting, the actual Datum doesn't need to be
9643
+ * changed, only the array metadata.
9644
+ */
9645
+
9646
+ int one = 1 ;
9647
+ bool isNull ;
9648
+ Datum valuesAtt [Natts_pg_attribute ];
9649
+ bool nullsAtt [Natts_pg_attribute ];
9650
+ bool replacesAtt [Natts_pg_attribute ];
9651
+
9652
+ MemSet (valuesAtt , 0 , sizeof (valuesAtt ));
9653
+ MemSet (nullsAtt , false, sizeof (nullsAtt ));
9654
+ MemSet (replacesAtt , false, sizeof (replacesAtt ));
9655
+
9656
+ missingval = array_get_element (missingval ,
9657
+ 1 ,
9658
+ & one ,
9659
+ 0 ,
9660
+ attTup -> attlen ,
9661
+ attTup -> attbyval ,
9662
+ attTup -> attalign ,
9663
+ & isNull );
9664
+ missingval = PointerGetDatum (
9665
+ construct_array (& missingval ,
9666
+ 1 ,
9667
+ targettype ,
9668
+ tform -> typlen ,
9669
+ tform -> typbyval ,
9670
+ tform -> typalign ));
9671
+
9672
+ valuesAtt [Anum_pg_attribute_attmissingval - 1 ] = missingval ;
9673
+ replacesAtt [Anum_pg_attribute_attmissingval - 1 ] = true;
9674
+ nullsAtt [Anum_pg_attribute_attmissingval - 1 ] = false;
9675
+
9676
+ heapTup = heap_modify_tuple (heapTup , RelationGetDescr (attrelation ),
9677
+ valuesAtt , nullsAtt , replacesAtt );
9678
+ attTup = (Form_pg_attribute ) GETSTRUCT (heapTup );
9679
+ }
9680
+ }
9681
+
9605
9682
attTup -> atttypid = targettype ;
9606
9683
attTup -> atttypmod = targettypmod ;
9607
9684
attTup -> attcollation = targetcollid ;
0 commit comments