@@ -305,7 +305,9 @@ typedef struct IndexDef
305
305
char * table ; /* table name including schema */
306
306
char * type ; /* btree, hash, gist or gin */
307
307
char * columns ; /* column definition */
308
- char * options ; /* options after columns. WITH, TABLESPACE and WHERE */
308
+ char * options ; /* options after columns, before TABLESPACE (e.g. COLLATE) */
309
+ char * tablespace ; /* tablespace if specified */
310
+ char * where ; /* WHERE content if specified */
309
311
} IndexDef ;
310
312
311
313
static char *
@@ -349,14 +351,14 @@ skip_const(Oid index, char *sql, const char *arg1, const char *arg2)
349
351
static char *
350
352
skip_until_const (Oid index , char * sql , const char * what )
351
353
{
352
- char * pos ;
354
+ char * pos ;
353
355
354
356
if ((pos = strstr (sql , what )))
355
357
{
356
- size_t len ;
358
+ size_t len ;
357
359
358
- len = strlen (what );
359
- pos [len ] = '\0' ;
360
+ len = strlen (what );
361
+ pos [-1 ] = '\0' ;
360
362
return pos + len + 1 ;
361
363
}
362
364
@@ -462,6 +464,7 @@ parse_indexdef(IndexDef *stmt, Oid index, Oid table)
462
464
char * sql = pg_get_indexdef_string (index );
463
465
const char * idxname = get_quoted_relname (index );
464
466
const char * tblname = get_relation_name (table );
467
+ const char * limit = strchr (sql , '\0' );
465
468
466
469
/* CREATE [UNIQUE] INDEX */
467
470
stmt -> create = sql ;
@@ -486,8 +489,36 @@ parse_indexdef(IndexDef *stmt, Oid index, Oid table)
486
489
stmt -> columns = sql ;
487
490
if ((sql = skip_until (index , sql , ')' )) == NULL )
488
491
parse_error (index );
492
+
489
493
/* options */
490
494
stmt -> options = sql ;
495
+ stmt -> tablespace = NULL ;
496
+ stmt -> where = NULL ;
497
+
498
+ /* Is there a tablespace? Note that apparently there is never, but
499
+ * if there was one it would appear here. */
500
+ if (sql < limit && strstr (sql , "TABLESPACE" ))
501
+ {
502
+ sql = skip_until_const (index , sql , "TABLESPACE" );
503
+ stmt -> tablespace = sql ;
504
+ sql = skip_ident (index , sql );
505
+ }
506
+
507
+ /* Note: assuming WHERE is the only clause allowed after TABLESPACE */
508
+ if (sql < limit && strstr (sql , "WHERE" ))
509
+ {
510
+ sql = skip_until_const (index , sql , "WHERE" );
511
+ stmt -> where = sql ;
512
+ }
513
+
514
+ elog (DEBUG2 , "indexdef.create = %s" , stmt -> create );
515
+ elog (DEBUG2 , "indexdef.index = %s" , stmt -> index );
516
+ elog (DEBUG2 , "indexdef.table = %s" , stmt -> table );
517
+ elog (DEBUG2 , "indexdef.type = %s" , stmt -> type );
518
+ elog (DEBUG2 , "indexdef.columns = %s" , stmt -> columns );
519
+ elog (DEBUG2 , "indexdef.options = %s" , stmt -> options );
520
+ elog (DEBUG2 , "indexdef.tspace = %s" , stmt -> tablespace );
521
+ elog (DEBUG2 , "indexdef.where = %s" , stmt -> where );
491
522
}
492
523
493
524
/*
@@ -546,12 +577,6 @@ repack_get_order_by(PG_FUNCTION_ARGS)
546
577
int nattr ;
547
578
548
579
parse_indexdef (& stmt , index , table );
549
- elog (DEBUG2 , "indexdef.create = %s" , stmt .create );
550
- elog (DEBUG2 , "indexdef.index = %s" , stmt .index );
551
- elog (DEBUG2 , "indexdef.table = %s" , stmt .table );
552
- elog (DEBUG2 , "indexdef.type = %s" , stmt .type );
553
- elog (DEBUG2 , "indexdef.columns = %s" , stmt .columns );
554
- elog (DEBUG2 , "indexdef.options = %s" , stmt .options );
555
580
556
581
/*
557
582
* FIXME: this is very unreliable implementation but I don't want to
@@ -660,36 +685,16 @@ repack_indexdef(PG_FUNCTION_ARGS)
660
685
parse_indexdef (& stmt , index , table );
661
686
662
687
initStringInfo (& str );
663
- appendStringInfo (& str , "%s index_%u ON repack.table_%u USING %s (%s)" ,
664
- stmt .create , index , table , stmt .type , stmt .columns );
688
+ appendStringInfo (& str , "%s index_%u ON repack.table_%u USING %s (%s)%s " ,
689
+ stmt .create , index , table , stmt .type , stmt .columns , stmt . options );
665
690
666
- /* Replace the tablespace in the index options */
667
- if (tablespace == NULL )
668
- {
669
- /* tablespace is just fine */
670
- appendStringInfoString (& str , stmt .options );
671
- }
672
- else
673
- {
674
- if (NULL == strstr (stmt .options , "TABLESPACE" ))
675
- {
676
- /* tablespace is to append */
677
- appendStringInfoString (& str , " TABLESPACE " );
678
- appendStringInfoString (& str , NameStr (* tablespace ));
679
- }
680
- else
681
- {
682
- /* tablespace is to replace */
683
- char * tmp , * limit ;
684
- limit = strchr (stmt .options , '\0' );
685
- tmp = skip_until_const (index , stmt .options , " TABLESPACE" );
686
- appendStringInfoString (& str , stmt .options );
687
- appendStringInfo (& str , " %s" , NameStr (* tablespace ));
688
- tmp = skip_ident (index , tmp );
689
- if (tmp < limit )
690
- appendStringInfo (& str , " %s" , tmp );
691
- }
692
- }
691
+ /* specify the new tablespace or the original one if any */
692
+ if (tablespace || stmt .tablespace )
693
+ appendStringInfo (& str , " TABLESPACE %s" ,
694
+ (tablespace ? NameStr (* tablespace ) : stmt .tablespace ));
695
+
696
+ if (stmt .where )
697
+ appendStringInfo (& str , " WHERE %s" , stmt .where );
693
698
694
699
PG_RETURN_TEXT_P (cstring_to_text (str .data ));
695
700
}
0 commit comments