@@ -144,14 +144,14 @@ def test_sync_table_full(self, mock_open_conn):
144144 # Verify metadata columns are in the query (tests _prepend_metadata_columns indirectly)
145145 export_query = self ._extract_export_query (mock_cursor )
146146 self .assertIsNotNone (export_query )
147- self .assertIn ("_SDC_BATCHED_AT " , export_query )
148- self .assertIn ("_SDC_DELETED_AT " , export_query )
149- self .assertIn ("_SDC_EXTRACTED_AT " , export_query )
150-
151- # Verify metadata columns order
152- batched_pos = export_query .find ("_SDC_BATCHED_AT " )
153- deleted_pos = export_query .find ("_SDC_DELETED_AT " )
154- extracted_pos = export_query .find ("_SDC_EXTRACTED_AT " )
147+ self .assertIn ("_sdc_batched_at " , export_query )
148+ self .assertIn ("_sdc_deleted_at " , export_query )
149+ self .assertIn ("_sdc_extracted_at " , export_query )
150+
151+ # Verify metadata columns are present and in correct order
152+ batched_pos = export_query .find ("_sdc_batched_at " )
153+ deleted_pos = export_query .find ("_sdc_deleted_at " )
154+ extracted_pos = export_query .find ("_sdc_extracted_at " )
155155 id_pos = export_query .find ('"id"' )
156156
157157 self .assertGreater (batched_pos , 0 )
@@ -160,6 +160,65 @@ def test_sync_table_full(self, mock_open_conn):
160160 if id_pos > 0 :
161161 self .assertGreater (id_pos , extracted_pos )
162162
163+ @patch ("tap_postgres.sync_strategies.fast_sync_rds.post_db.open_connection" )
164+ def test_sync_table_full_column_ordering (self , mock_open_conn ):
165+ """Test sync_table_full orders columns alphabetically including metadata columns"""
166+ desired_columns = ["zebra" , "_id" , "active" ]
167+ md_map_with_columns = {
168+ (): {"schema-name" : "test_schema" },
169+ ("properties" , "_id" ): {"sql-datatype" : "integer" },
170+ ("properties" , "active" ): {"sql-datatype" : "boolean" },
171+ ("properties" , "zebra" ): {"sql-datatype" : "varchar" },
172+ }
173+
174+ mock_conn , mock_cursor = self ._setup_mock_connection ()
175+ mock_open_conn .return_value .__enter__ .return_value = mock_conn
176+
177+ self .fast_sync_rds_strategy .sync_table_full (
178+ stream = self .stream ,
179+ state = self .state ,
180+ desired_columns = desired_columns ,
181+ md_map = md_map_with_columns ,
182+ )
183+
184+ # Verify export query contains all columns
185+ export_query = self ._extract_export_query (mock_cursor )
186+ self .assertIsNotNone (export_query )
187+ self .assertIn ("_sdc_batched_at" , export_query )
188+ self .assertIn ("_sdc_deleted_at" , export_query )
189+ self .assertIn ("_sdc_extracted_at" , export_query )
190+ self .assertIn ('"_id"' , export_query )
191+ self .assertIn ('"active"' , export_query )
192+ self .assertIn ('"zebra"' , export_query )
193+
194+ # Verify complete column ordering: all columns should be sorted alphabetically
195+ # Expected order: _id, _sdc_batched_at, _sdc_deleted_at, _sdc_extracted_at, active, zebra
196+ expected_columns = [
197+ '"_id"' ,
198+ "_sdc_batched_at" ,
199+ "_sdc_deleted_at" ,
200+ "_sdc_extracted_at" ,
201+ '"active"' ,
202+ '"zebra"' ,
203+ ]
204+
205+ # Find positions of all columns
206+ column_positions = [export_query .find (col ) for col in expected_columns ]
207+
208+ self .assertEqual (len (column_positions ), len (expected_columns ))
209+
210+ # Verify all columns are found
211+ for i , (col , pos ) in enumerate (zip (expected_columns , column_positions )):
212+ self .assertGreater (pos , 0 , f"{ col } should be found in query" )
213+
214+ # Verify columns are in correct order (positions should be ascending)
215+ self .assertEqual (
216+ column_positions ,
217+ sorted (column_positions ),
218+ f"Columns should be in alphabetical order. Found positions: { dict (zip (expected_columns , column_positions ))} " ,
219+ )
220+
221+
163222 @patch ("tap_postgres.sync_strategies.fast_sync_rds.post_db.open_connection" )
164223 def test_sync_table_full_no_prefix (self , mock_open_conn ):
165224 """Test sync_table_full with empty prefix - verifies S3 path generation"""
@@ -205,9 +264,9 @@ def test_sync_table_full_metadata_columns_disabled(self, mock_open_conn):
205264 # Verify metadata columns are NOT in the query
206265 export_query = self ._extract_export_query (mock_cursor )
207266 self .assertIsNotNone (export_query )
208- self .assertNotIn ("_SDC_BATCHED_AT " , export_query )
209- self .assertNotIn ("_SDC_DELETED_AT " , export_query )
210- self .assertNotIn ("_SDC_EXTRACTED_AT " , export_query )
267+ self .assertNotIn ("_sdc_batched_at " , export_query )
268+ self .assertNotIn ("_sdc_deleted_at " , export_query )
269+ self .assertNotIn ("_sdc_extracted_at " , export_query )
211270
212271 @patch ("tap_postgres.sync_strategies.fast_sync_rds.post_db.open_connection" )
213272 @patch ("tap_postgres.sync_strategies.fast_sync_rds.singer.get_bookmark" )
0 commit comments