3434#include "funcapi.h"
3535#include "miscadmin.h"
3636#include "nodes/makefuncs.h"
37+ #include "parser/parse_type.h"
3738#include "storage/lmgr.h"
3839#include "storage/proc.h"
3940#include "storage/smgr.h"
@@ -229,12 +230,13 @@ DefineSequence(ParseState *pstate, CreateSeqStmt *seq)
229230 memset (pgs_nulls , 0 , sizeof (pgs_nulls ));
230231
231232 pgs_values [Anum_pg_sequence_seqrelid - 1 ] = ObjectIdGetDatum (seqoid );
232- pgs_values [Anum_pg_sequence_seqcycle - 1 ] = BoolGetDatum (seqform .seqcycle );
233+ pgs_values [Anum_pg_sequence_seqtypid - 1 ] = ObjectIdGetDatum (seqform .seqtypid );
233234 pgs_values [Anum_pg_sequence_seqstart - 1 ] = Int64GetDatumFast (seqform .seqstart );
234235 pgs_values [Anum_pg_sequence_seqincrement - 1 ] = Int64GetDatumFast (seqform .seqincrement );
235236 pgs_values [Anum_pg_sequence_seqmax - 1 ] = Int64GetDatumFast (seqform .seqmax );
236237 pgs_values [Anum_pg_sequence_seqmin - 1 ] = Int64GetDatumFast (seqform .seqmin );
237238 pgs_values [Anum_pg_sequence_seqcache - 1 ] = Int64GetDatumFast (seqform .seqcache );
239+ pgs_values [Anum_pg_sequence_seqcycle - 1 ] = BoolGetDatum (seqform .seqcycle );
238240
239241 tuple = heap_form_tuple (tupDesc , pgs_values , pgs_nulls );
240242 CatalogTupleInsert (rel , tuple );
@@ -622,11 +624,11 @@ nextval_internal(Oid relid)
622624 if (!HeapTupleIsValid (pgstuple ))
623625 elog (ERROR , "cache lookup failed for sequence %u" , relid );
624626 pgsform = (Form_pg_sequence ) GETSTRUCT (pgstuple );
625- cycle = pgsform -> seqcycle ;
626627 incby = pgsform -> seqincrement ;
627628 maxv = pgsform -> seqmax ;
628629 minv = pgsform -> seqmin ;
629630 cache = pgsform -> seqcache ;
631+ cycle = pgsform -> seqcycle ;
630632 ReleaseSysCache (pgstuple );
631633
632634 /* lock page' buffer and read tuple */
@@ -1221,6 +1223,7 @@ init_params(ParseState *pstate, List *options, bool isInit,
12211223 Form_pg_sequence seqform ,
12221224 Form_pg_sequence_data seqdataform , List * * owned_by )
12231225{
1226+ DefElem * as_type = NULL ;
12241227 DefElem * start_value = NULL ;
12251228 DefElem * restart_value = NULL ;
12261229 DefElem * increment_by = NULL ;
@@ -1236,7 +1239,16 @@ init_params(ParseState *pstate, List *options, bool isInit,
12361239 {
12371240 DefElem * defel = (DefElem * ) lfirst (option );
12381241
1239- if (strcmp (defel -> defname , "increment" ) == 0 )
1242+ if (strcmp (defel -> defname , "as" ) == 0 )
1243+ {
1244+ if (as_type )
1245+ ereport (ERROR ,
1246+ (errcode (ERRCODE_SYNTAX_ERROR ),
1247+ errmsg ("conflicting or redundant options" ),
1248+ parser_errposition (pstate , defel -> location )));
1249+ as_type = defel ;
1250+ }
1251+ else if (strcmp (defel -> defname , "increment" ) == 0 )
12401252 {
12411253 if (increment_by )
12421254 ereport (ERROR ,
@@ -1320,6 +1332,20 @@ init_params(ParseState *pstate, List *options, bool isInit,
13201332 if (isInit )
13211333 seqdataform -> log_cnt = 0 ;
13221334
1335+ /* AS type */
1336+ if (as_type != NULL )
1337+ {
1338+ seqform -> seqtypid = typenameTypeId (pstate , defGetTypeName (as_type ));
1339+ if (seqform -> seqtypid != INT2OID &&
1340+ seqform -> seqtypid != INT4OID &&
1341+ seqform -> seqtypid != INT8OID )
1342+ ereport (ERROR ,
1343+ (errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
1344+ errmsg ("sequence type must be smallint, integer, or bigint" )));
1345+ }
1346+ else if (isInit )
1347+ seqform -> seqtypid = INT8OID ;
1348+
13231349 /* INCREMENT BY */
13241350 if (increment_by != NULL )
13251351 {
@@ -1352,12 +1378,34 @@ init_params(ParseState *pstate, List *options, bool isInit,
13521378 else if (isInit || max_value != NULL )
13531379 {
13541380 if (seqform -> seqincrement > 0 )
1355- seqform -> seqmax = PG_INT64_MAX ; /* ascending seq */
1381+ {
1382+ /* ascending seq */
1383+ if (seqform -> seqtypid == INT2OID )
1384+ seqform -> seqmax = PG_INT16_MAX ;
1385+ else if (seqform -> seqtypid == INT4OID )
1386+ seqform -> seqmax = PG_INT32_MAX ;
1387+ else
1388+ seqform -> seqmax = PG_INT64_MAX ;
1389+ }
13561390 else
13571391 seqform -> seqmax = -1 ; /* descending seq */
13581392 seqdataform -> log_cnt = 0 ;
13591393 }
13601394
1395+ if ((seqform -> seqtypid == INT2OID && (seqform -> seqmax < PG_INT16_MIN || seqform -> seqmax > PG_INT16_MAX ))
1396+ || (seqform -> seqtypid == INT4OID && (seqform -> seqmax < PG_INT32_MIN || seqform -> seqmax > PG_INT32_MAX ))
1397+ || (seqform -> seqtypid == INT8OID && (seqform -> seqmax < PG_INT64_MIN || seqform -> seqmax > PG_INT64_MAX )))
1398+ {
1399+ char bufx [100 ];
1400+
1401+ snprintf (bufx , sizeof (bufx ), INT64_FORMAT , seqform -> seqmax );
1402+
1403+ ereport (ERROR ,
1404+ (errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
1405+ errmsg ("MAXVALUE (%s) is out of range for sequence data type %s" ,
1406+ bufx , format_type_be (seqform -> seqtypid ))));
1407+ }
1408+
13611409 /* MINVALUE (null arg means NO MINVALUE) */
13621410 if (min_value != NULL && min_value -> arg )
13631411 {
@@ -1369,10 +1417,32 @@ init_params(ParseState *pstate, List *options, bool isInit,
13691417 if (seqform -> seqincrement > 0 )
13701418 seqform -> seqmin = 1 ; /* ascending seq */
13711419 else
1372- seqform -> seqmin = PG_INT64_MIN ; /* descending seq */
1420+ {
1421+ /* descending seq */
1422+ if (seqform -> seqtypid == INT2OID )
1423+ seqform -> seqmin = PG_INT16_MIN ;
1424+ else if (seqform -> seqtypid == INT4OID )
1425+ seqform -> seqmin = PG_INT32_MIN ;
1426+ else
1427+ seqform -> seqmin = PG_INT64_MIN ;
1428+ }
13731429 seqdataform -> log_cnt = 0 ;
13741430 }
13751431
1432+ if ((seqform -> seqtypid == INT2OID && (seqform -> seqmin < PG_INT16_MIN || seqform -> seqmin > PG_INT16_MAX ))
1433+ || (seqform -> seqtypid == INT4OID && (seqform -> seqmin < PG_INT32_MIN || seqform -> seqmin > PG_INT32_MAX ))
1434+ || (seqform -> seqtypid == INT8OID && (seqform -> seqmin < PG_INT64_MIN || seqform -> seqmin > PG_INT64_MAX )))
1435+ {
1436+ char bufm [100 ];
1437+
1438+ snprintf (bufm , sizeof (bufm ), INT64_FORMAT , seqform -> seqmin );
1439+
1440+ ereport (ERROR ,
1441+ (errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
1442+ errmsg ("MINVALUE (%s) is out of range for sequence data type %s" ,
1443+ bufm , format_type_be (seqform -> seqtypid ))));
1444+ }
1445+
13761446 /* crosscheck min/max */
13771447 if (seqform -> seqmin >= seqform -> seqmax )
13781448 {
@@ -1590,8 +1660,8 @@ pg_sequence_parameters(PG_FUNCTION_ARGS)
15901660{
15911661 Oid relid = PG_GETARG_OID (0 );
15921662 TupleDesc tupdesc ;
1593- Datum values [6 ];
1594- bool isnull [6 ];
1663+ Datum values [7 ];
1664+ bool isnull [7 ];
15951665 HeapTuple pgstuple ;
15961666 Form_pg_sequence pgsform ;
15971667
@@ -1601,7 +1671,7 @@ pg_sequence_parameters(PG_FUNCTION_ARGS)
16011671 errmsg ("permission denied for sequence %s" ,
16021672 get_rel_name (relid ))));
16031673
1604- tupdesc = CreateTemplateTupleDesc (6 , false);
1674+ tupdesc = CreateTemplateTupleDesc (7 , false);
16051675 TupleDescInitEntry (tupdesc , (AttrNumber ) 1 , "start_value" ,
16061676 INT8OID , -1 , 0 );
16071677 TupleDescInitEntry (tupdesc , (AttrNumber ) 2 , "minimum_value" ,
@@ -1614,6 +1684,8 @@ pg_sequence_parameters(PG_FUNCTION_ARGS)
16141684 BOOLOID , -1 , 0 );
16151685 TupleDescInitEntry (tupdesc , (AttrNumber ) 6 , "cache_size" ,
16161686 INT8OID , -1 , 0 );
1687+ TupleDescInitEntry (tupdesc , (AttrNumber ) 7 , "data_type" ,
1688+ OIDOID , -1 , 0 );
16171689
16181690 BlessTupleDesc (tupdesc );
16191691
@@ -1630,6 +1702,7 @@ pg_sequence_parameters(PG_FUNCTION_ARGS)
16301702 values [3 ] = Int64GetDatum (pgsform -> seqincrement );
16311703 values [4 ] = BoolGetDatum (pgsform -> seqcycle );
16321704 values [5 ] = Int64GetDatum (pgsform -> seqcache );
1705+ values [6 ] = ObjectIdGetDatum (pgsform -> seqtypid );
16331706
16341707 ReleaseSysCache (pgstuple );
16351708
0 commit comments