22
22
#include <utils/lsyscache.h>
23
23
#include <utils/syscache.h>
24
24
#include <utils/builtins.h>
25
+ #include <utils/guc.h>
25
26
#include <utils/snapmgr.h>
26
27
#include <parser/parse_utilcmd.h>
27
28
@@ -50,14 +51,6 @@ static ProcessUtility_hook_type prev_ProcessUtility_hook;
50
51
51
52
static bool expect_chunk_modification = false;
52
53
53
- /* Macros for DDL upcalls to PL/pgSQL */
54
-
55
- #define process_truncate_hypertable (hypertable , cascade ) \
56
- CatalogInternalCall3(TRUNCATE_HYPERTABLE, \
57
- NameGetDatum(&(hypertable)->fd.schema_name), \
58
- NameGetDatum(&(hypertable)->fd.table_name), \
59
- BoolGetDatum(cascade))
60
-
61
54
typedef struct ProcessUtilityArgs
62
55
{
63
56
#if PG10
@@ -147,37 +140,6 @@ relation_not_only(RangeVar *rv)
147
140
errmsg ("ONLY option not supported on hypertable operations" )));
148
141
}
149
142
150
- /* Truncate a hypertable */
151
- static void
152
- process_truncate (Node * parsetree )
153
- {
154
- TruncateStmt * truncatestmt = (TruncateStmt * ) parsetree ;
155
- Cache * hcache = hypertable_cache_pin ();
156
- ListCell * cell ;
157
-
158
- foreach (cell , truncatestmt -> relations )
159
- {
160
- RangeVar * relation = lfirst (cell );
161
- Oid relid ;
162
-
163
- if (NULL == relation )
164
- continue ;
165
-
166
- relid = RangeVarGetRelid (relation , NoLock , true);
167
-
168
- if (OidIsValid (relid ))
169
- {
170
- Hypertable * ht = hypertable_cache_get_entry (hcache , relid );
171
-
172
- if (ht != NULL )
173
- {
174
- process_truncate_hypertable (ht , truncatestmt -> behavior == DROP_CASCADE );
175
- }
176
- }
177
- }
178
- cache_release (hcache );
179
- }
180
-
181
143
/* Change the schema of a hypertable */
182
144
static void
183
145
process_alterobjectschema (Node * parsetree )
@@ -358,6 +320,77 @@ process_vacuum(Node *parsetree, ProcessUtilityContext context)
358
320
return true;
359
321
}
360
322
323
+ static void
324
+ process_truncate_chunk (Hypertable * ht , Oid chunk_relid , void * arg )
325
+ {
326
+ TruncateStmt * stmt = arg ;
327
+ ObjectAddress objaddr = {
328
+ .classId = RelationRelationId ,
329
+ .objectId = chunk_relid ,
330
+ };
331
+
332
+ performDeletion (& objaddr , stmt -> behavior , 0 );
333
+ }
334
+
335
+ #if PG10
336
+ #define TRUNCATE_RECURSE (rv ) \
337
+ (rv)->inh
338
+ #elif PG96
339
+ #define TRUNCATE_RECURSE (rv ) \
340
+ ((rv)->inhOpt == INH_DEFAULT ? SQL_inheritance : ((rv)->inhOpt == INH_YES))
341
+ #endif
342
+
343
+ /*
344
+ * Truncate a hypertable.
345
+ */
346
+ static bool
347
+ process_truncate (ProcessUtilityArgs * args )
348
+ {
349
+ TruncateStmt * stmt = (TruncateStmt * ) args -> parsetree ;
350
+ Cache * hcache = hypertable_cache_pin ();
351
+ ListCell * cell ;
352
+
353
+ /* Call standard process utility first to truncate all tables */
354
+ prev_ProcessUtility (args );
355
+
356
+ /* For all hypertables, we drop the now empty chunks */
357
+ foreach (cell , stmt -> relations )
358
+ {
359
+ RangeVar * rv = lfirst (cell );
360
+ Oid relid ;
361
+
362
+ if (NULL == rv )
363
+ continue ;
364
+
365
+ relid = RangeVarGetRelid (rv , NoLock , true);
366
+
367
+ if (OidIsValid (relid ))
368
+ {
369
+ Hypertable * ht = hypertable_cache_get_entry (hcache , relid );
370
+
371
+ if (ht != NULL )
372
+ {
373
+ if (!TRUNCATE_RECURSE (rv ))
374
+ ereport (ERROR ,
375
+ (errcode (ERRCODE_WRONG_OBJECT_TYPE ),
376
+ errmsg ("cannot truncate only a hypertable" ),
377
+ errhint ("Do not specify the ONLY keyword, or use truncate"
378
+ " only on the chunks directly." )));
379
+
380
+ /* Delete the metadata */
381
+ chunk_delete_by_hypertable_id (ht -> fd .id );
382
+
383
+ /* Drop the chunk tables */
384
+ foreach_chunk (ht , process_truncate_chunk , stmt );
385
+ }
386
+ }
387
+ }
388
+
389
+ cache_release (hcache );
390
+
391
+ return true;
392
+ }
393
+
361
394
static void
362
395
process_drop_table_chunk (Hypertable * ht , Oid chunk_relid , void * arg )
363
396
{
@@ -1628,32 +1661,29 @@ process_create_trigger_end(Node *parsetree)
1628
1661
* Handle DDL commands before they have been processed by PostgreSQL.
1629
1662
*/
1630
1663
static bool
1631
- process_ddl_command_start (Node * parsetree ,
1632
- const char * query_string ,
1633
- ProcessUtilityContext context ,
1634
- char * completion_tag )
1664
+ process_ddl_command_start (ProcessUtilityArgs * args )
1635
1665
{
1636
1666
bool handled = false;
1637
1667
1638
- switch (nodeTag (parsetree ))
1668
+ switch (nodeTag (args -> parsetree ))
1639
1669
{
1640
- case T_TruncateStmt :
1641
- process_truncate (parsetree );
1642
- break ;
1643
1670
case T_AlterObjectSchemaStmt :
1644
- process_alterobjectschema (parsetree );
1671
+ process_alterobjectschema (args -> parsetree );
1672
+ break ;
1673
+ case T_TruncateStmt :
1674
+ handled = process_truncate (args );
1645
1675
break ;
1646
1676
case T_AlterTableStmt :
1647
- process_altertable_start (parsetree );
1677
+ process_altertable_start (args -> parsetree );
1648
1678
break ;
1649
1679
case T_RenameStmt :
1650
- process_rename (parsetree );
1680
+ process_rename (args -> parsetree );
1651
1681
break ;
1652
1682
case T_IndexStmt :
1653
- process_index_start (parsetree );
1683
+ process_index_start (args -> parsetree );
1654
1684
break ;
1655
1685
case T_CreateTrigStmt :
1656
- process_create_trigger_start (parsetree );
1686
+ process_create_trigger_start (args -> parsetree );
1657
1687
break ;
1658
1688
case T_DropStmt :
1659
1689
@@ -1663,19 +1693,19 @@ process_ddl_command_start(Node *parsetree,
1663
1693
* table is dropped, the drop respects CASCADE in the expected
1664
1694
* way.
1665
1695
*/
1666
- process_drop (parsetree );
1696
+ process_drop (args -> parsetree );
1667
1697
break ;
1668
1698
case T_CopyStmt :
1669
- handled = process_copy (parsetree , query_string , completion_tag );
1699
+ handled = process_copy (args -> parsetree , args -> query_string , args -> completion_tag );
1670
1700
break ;
1671
1701
case T_VacuumStmt :
1672
- handled = process_vacuum (parsetree , context );
1702
+ handled = process_vacuum (args -> parsetree , args -> context );
1673
1703
break ;
1674
1704
case T_ReindexStmt :
1675
- handled = process_reindex (parsetree );
1705
+ handled = process_reindex (args -> parsetree );
1676
1706
break ;
1677
1707
case T_ClusterStmt :
1678
- handled = process_cluster_start (parsetree , context );
1708
+ handled = process_cluster_start (args -> parsetree , args -> context );
1679
1709
break ;
1680
1710
default :
1681
1711
break ;
@@ -1762,10 +1792,7 @@ timescaledb_ddl_command_start(
1762
1792
return ;
1763
1793
}
1764
1794
1765
- if (!process_ddl_command_start (args .parsetree ,
1766
- args .query_string ,
1767
- args .context ,
1768
- args .completion_tag ))
1795
+ if (!process_ddl_command_start (& args ))
1769
1796
prev_ProcessUtility (& args );
1770
1797
}
1771
1798
0 commit comments