Skip to content

Commit c53c1c4

Browse files
authored
Merge pull request #922 from yuanyl630/IVORY_REL_5_STABLE
refactor rowid codes
2 parents 8b91dee + 6b077e2 commit c53c1c4

File tree

8 files changed

+83
-58
lines changed

8 files changed

+83
-58
lines changed

contrib/ivorysql_ora/preload_ora_misc.sql

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ insert into dual values('X');
66
GRANT SELECT ON dual TO PUBLIC;
77

88
--
9-
-- ROWID type
9+
-- Oracle-compatible ROWID and UROWID types
10+
-- ROWID: Composite type containing row object ID and row number
11+
-- UROWID: Universal ROWID, compatible with ROWID
1012
--
1113
CREATE TYPE sys.rowid AS(rowoid OID, rowno bigint);
1214
CREATE TYPE sys.urowid AS(rowoid OID, rowno bigint);

contrib/tablefunc/expected/ivy_tablefunc.out

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ SELECT avg(normal_rand)::int, count(*) FROM normal_rand(-1, 250, 0.2);
1414
ERROR: number of rows cannot be negative
1515
--
1616
-- crosstab()
17+
-- Use 'orarowid' instead of 'rowid' to avoid conflict with system column
1718
--
1819
CREATE TABLE ct(id int, rowclass text, orarowid text, attribute text, val text);
1920
\copy ct from 'data/ct.data'

contrib/tablefunc/sql/ivy_tablefunc.sql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ SELECT avg(normal_rand)::int, count(*) FROM normal_rand(-1, 250, 0.2);
1010

1111
--
1212
-- crosstab()
13+
-- Use 'orarowid' instead of 'rowid' to avoid conflict with system column
1314
--
1415
CREATE TABLE ct(id int, rowclass text, orarowid text, attribute text, val text);
1516
\copy ct from 'data/ct.data'

src/backend/catalog/heap.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,9 @@ static const FormData_pg_attribute a6 = {
228228
};
229229

230230
/*
231-
* Compatible Oracle ROWID pseudo column.
231+
* Oracle-compatible ROWID pseudo-column.
232+
* This system column provides a unique identifier for each row,
233+
* compatible with Oracle's ROWID functionality.
232234
*/
233235
static const FormData_pg_attribute a7 = {
234236
.attname = {"rowid"},

src/backend/parser/parse_utilcmd.c

Lines changed: 60 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@
6868
#include "utils/ruleutils.h"
6969
#include "utils/syscache.h"
7070
#include "utils/typcache.h"
71-
#include <math.h>
71+
#include <math.h>
7272
#include "utils/guc.h"
7373
#include "utils/ora_compatible.h"
7474

@@ -280,10 +280,12 @@ transformCreateStmt(CreateStmt *stmt, const char *queryString)
280280
if (cxt.inhRelations)
281281
{
282282
ListCell *inher;
283+
283284
foreach(inher, cxt.inhRelations)
284285
{
285286
RangeVar *inh = lfirst_node(RangeVar, inher);
286287
Relation prel;
288+
287289
prel = table_openrv(inh, AccessShareLock);
288290
cxt.hasrowid = cxt.hasrowid || prel->rd_rel->relhasrowid;
289291
table_close(prel, NoLock);
@@ -302,7 +304,8 @@ transformCreateStmt(CreateStmt *stmt, const char *queryString)
302304
{
303305
case T_ColumnDef:
304306
{
305-
ColumnDef *col = (ColumnDef *) element;
307+
ColumnDef *col = (ColumnDef *) element;
308+
306309
if (compatible_db == ORA_PARSER && strcmp(col->colname, "rowid") == 0)
307310
elog(ERROR, "column name \"%s\" conflicts with a system column name", col->colname);
308311
else
@@ -331,13 +334,14 @@ transformCreateStmt(CreateStmt *stmt, const char *queryString)
331334
*/
332335
foreach(elements, cxt.columns)
333336
{
334-
ColumnDef *element = lfirst(elements);
335-
if(element->identity == ATTRIBUTE_IDENTITY_DEFAULT_ON_NULL ||
336-
element->identity == ATTRIBUTE_ORA_IDENTITY_ALWAYS ||
337-
element->identity == ATTRIBUTE_ORA_IDENTITY_BY_DEFAULT)
337+
ColumnDef *element = lfirst(elements);
338+
339+
if (element->identity == ATTRIBUTE_IDENTITY_DEFAULT_ON_NULL ||
340+
element->identity == ATTRIBUTE_ORA_IDENTITY_ALWAYS ||
341+
element->identity == ATTRIBUTE_ORA_IDENTITY_BY_DEFAULT)
338342
ora_identity_cnt++;
339343
}
340-
if(ora_identity_cnt > 1)
344+
if (ora_identity_cnt > 1)
341345
elog(ERROR, "table can have only one identity column");
342346

343347
if (like_found && cxt.hasrowid)
@@ -348,7 +352,7 @@ transformCreateStmt(CreateStmt *stmt, const char *queryString)
348352

349353
if (cxt.hasrowid)
350354
{
351-
Oid snamespaceid;
355+
Oid snamespaceid;
352356
char *snamespace;
353357
char *sname;
354358

@@ -368,47 +372,48 @@ transformCreateStmt(CreateStmt *stmt, const char *queryString)
368372
false);
369373

370374
/*
371-
* Build a CREATE SEQUENCE command to create the sequence object,
372-
* and add it to the list of things to be done before this CREATE/ALTER TABLE
375+
* Build a CREATE SEQUENCE command to create the sequence object, and
376+
* add it to the list of things to be done before this CREATE/ALTER
377+
* TABLE
373378
*/
374379
seqstmt = makeNode(CreateSeqStmt);
375380
seqstmt->with_rowid = true;
376381
seqstmt->sequence = makeRangeVar(snamespace, sname, -1);
377382
seqstmt->options = lcons(makeDefElem("as",
378-
(Node *) makeTypeNameFromOid(INT8OID, -1),
379-
-1),
380-
seqstmt->options);
383+
(Node *) makeTypeNameFromOid(INT8OID, -1),
384+
-1),
385+
seqstmt->options);
381386
if (rowid_seq_cache > 1)
382387
{
383388
seqstmt->options = lcons(makeDefElem("cache",
384-
(Node *) makeInteger(rowid_seq_cache),
385-
-1),
386-
seqstmt->options);
389+
(Node *) makeInteger(rowid_seq_cache),
390+
-1),
391+
seqstmt->options);
387392
}
388393
else
389394
seqstmt->options = lcons(makeDefElem("nocache",
390-
NULL,
391-
-1),
392-
seqstmt->options);
395+
NULL,
396+
-1),
397+
seqstmt->options);
393398

394399
if (cxt.rel)
395400
seqstmt->ownerId = cxt.rel->rd_rel->relowner;
396401

397402
cxt.blist = lappend(cxt.blist, seqstmt);
398403

399404
/*
400-
* Build an ALTER SEQUENCE ... OWNED BY command to mark the sequence as owned
401-
* by this table.
405+
* Build an ALTER SEQUENCE ... OWNED BY command to mark the sequence
406+
* as owned by this table.
402407
*/
403408
altseqstmt = makeNode(AlterSeqStmt);
404409
altseqstmt->sequence = makeRangeVar(snamespace, sname, -1);
405410

406411
relnamelist = list_make3(makeString(snamespace),
407-
makeString(cxt.relation->relname),
408-
makeString(sname));
412+
makeString(cxt.relation->relname),
413+
makeString(sname));
409414

410415
altseqstmt->options = list_make1(makeDefElem("owned_by",
411-
(Node *) relnamelist, -1));
416+
(Node *) relnamelist, -1));
412417
cxt.alist = lappend(cxt.alist, altseqstmt);
413418
}
414419

@@ -971,11 +976,14 @@ transformColumnDefinition(CreateStmtContext *cxt, ColumnDef *column)
971976
ctype = typenameType(cxt->pstate, column->typeName, &typmod);
972977
typeOid = ((Form_pg_type) GETSTRUCT(ctype))->oid;
973978

974-
/* Convert compatible identity smallint/int type column to bigint type */
979+
/*
980+
* Convert compatible identity smallint/int type column to
981+
* bigint type
982+
*/
975983
if ((constraint->generated_when == ATTRIBUTE_IDENTITY_DEFAULT_ON_NULL
976-
|| constraint->generated_when == ATTRIBUTE_ORA_IDENTITY_ALWAYS
977-
|| constraint->generated_when == ATTRIBUTE_ORA_IDENTITY_BY_DEFAULT)
978-
&& (typeOid == INT4OID || typeOid == INT2OID))
984+
|| constraint->generated_when == ATTRIBUTE_ORA_IDENTITY_ALWAYS
985+
|| constraint->generated_when == ATTRIBUTE_ORA_IDENTITY_BY_DEFAULT)
986+
&& (typeOid == INT4OID || typeOid == INT2OID))
979987
{
980988
column->typeName = makeTypeName("int8");
981989
typeOid = INT8OID;
@@ -1296,7 +1304,7 @@ transformTableLikeClause(CreateStmtContext *cxt, TableLikeClause *table_like_cla
12961304
if (relation->rd_rel->relkind == RELKIND_COMPOSITE_TYPE)
12971305
{
12981306
aclresult = object_aclcheck(TypeRelationId, relation->rd_rel->reltype, GetUserId(),
1299-
ACL_USAGE);
1307+
ACL_USAGE);
13001308
if (aclresult != ACLCHECK_OK)
13011309
aclcheck_error(aclresult, OBJECT_TYPE,
13021310
RelationGetRelationName(relation));
@@ -2689,7 +2697,7 @@ transformIndexConstraint(Constraint *constraint, CreateStmtContext *cxt)
26892697
* mentioned above.
26902698
*/
26912699
Datum attoptions =
2692-
get_attoptions(RelationGetRelid(index_rel), i + 1);
2700+
get_attoptions(RelationGetRelid(index_rel), i + 1);
26932701

26942702
defopclass = GetDefaultOpClass(attform->atttypid,
26952703
index_rel->rd_rel->relam);
@@ -3764,12 +3772,12 @@ transformAlterTableStmt(Oid relid, AlterTableStmt *stmt,
37643772

37653773
case AT_AddRowidsRecurse:
37663774
{
3767-
Oid snamespaceid;
3768-
char *snamespace;
3769-
char *sname;
3770-
List *relnamelist;
3771-
CreateSeqStmt *seqstmt;
3772-
AlterSeqStmt *altseqstmt;
3775+
Oid snamespaceid;
3776+
char *snamespace;
3777+
char *sname;
3778+
List *relnamelist;
3779+
CreateSeqStmt *seqstmt;
3780+
AlterSeqStmt *altseqstmt;
37733781

37743782
if (cmd->is_rowid)
37753783
{
@@ -3789,45 +3797,46 @@ transformAlterTableStmt(Oid relid, AlterTableStmt *stmt,
37893797
false);
37903798

37913799
/*
3792-
* Build a CREATE SEQUENCE command to create the sequence object,
3793-
* and add it to the list of things to be done before this CREATE/ALTER TABLE
3800+
* Build a CREATE SEQUENCE command to create the
3801+
* sequence object, and add it to the list of things
3802+
* to be done before this CREATE/ALTER TABLE
37943803
*/
37953804
seqstmt = makeNode(CreateSeqStmt);
37963805
seqstmt->with_rowid = true;
37973806
seqstmt->sequence = makeRangeVar(snamespace, sname, -1);
37983807
seqstmt->options = lcons(makeDefElem("as",
3799-
(Node *) makeTypeNameFromOid(INT8OID, -1),
3800-
-1), seqstmt->options);
3808+
(Node *) makeTypeNameFromOid(INT8OID, -1),
3809+
-1), seqstmt->options);
38013810
if (rowid_seq_cache > 1)
38023811
{
38033812
seqstmt->options = lcons(makeDefElem("cache",
3804-
(Node *) makeInteger(rowid_seq_cache),
3805-
-1), seqstmt->options);
3813+
(Node *) makeInteger(rowid_seq_cache),
3814+
-1), seqstmt->options);
38063815
}
38073816
else
38083817
seqstmt->options = lcons(makeDefElem("nocache",
3809-
NULL,
3810-
-1),
3811-
seqstmt->options);
3818+
NULL,
3819+
-1),
3820+
seqstmt->options);
38123821

38133822
if (cxt.rel)
38143823
seqstmt->ownerId = cxt.rel->rd_rel->relowner;
38153824

38163825
cxt.blist = lappend(cxt.blist, seqstmt);
38173826

38183827
/*
3819-
* Build an ALTER SEQUENCE ... OWNED BY command to mark the sequence as owned
3820-
* by this table.
3828+
* Build an ALTER SEQUENCE ... OWNED BY command to
3829+
* mark the sequence as owned by this table.
38213830
*/
38223831
altseqstmt = makeNode(AlterSeqStmt);
38233832
altseqstmt->sequence = makeRangeVar(snamespace, sname, -1);
38243833

38253834
relnamelist = list_make3(makeString(snamespace),
3826-
makeString(cxt.relation->relname),
3827-
makeString(sname));
3835+
makeString(cxt.relation->relname),
3836+
makeString(sname));
38283837

38293838
altseqstmt->options = list_make1(makeDefElem("owned_by",
3830-
(Node *) relnamelist, -1));
3839+
(Node *) relnamelist, -1));
38313840
cxt.alist = lappend(cxt.alist, altseqstmt);
38323841

38333842
newcmds = lappend(newcmds, cmd);
@@ -4669,7 +4678,7 @@ transformPartitionRangeBounds(ParseState *pstate, List *blist,
46694678
* as ColumnRefs.
46704679
*/
46714680
if (IsA(expr, ColumnRef) ||
4672-
IsA(expr, ColumnRefOrFuncCall))
4681+
IsA(expr, ColumnRefOrFuncCall))
46734682
{
46744683
ColumnRef *cref = NULL;
46754684
char *cname = NULL;

src/backend/utils/misc/ivy_guc.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,9 +183,19 @@ static struct config_bool Ivy_ConfigureNamesBool[] =
183183
NULL, NULL, NULL
184184
},
185185

186+
/*
187+
* ivorysql.default_with_rowids
188+
*
189+
* When enabled, all newly created tables will automatically include
190+
* an Oracle-compatible ROWID pseudo-column. This provides compatibility
191+
* with Oracle applications that rely on ROWID for row identification.
192+
*
193+
* Default: off
194+
* Context: USERSET (can be changed by any user)
195+
*/
186196
{
187197
{"ivorysql.default_with_rowids", PGC_USERSET, DEVELOPER_OPTIONS,
188-
gettext_noop("Auto add rowid column for create new table."),
198+
gettext_noop("Automatically add rowid column when creating new tables."),
189199
NULL,
190200
GUC_NO_SHOW_ALL | GUC_NOT_IN_SAMPLE
191201
},

src/include/access/htup_details.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ struct HeapTupleHeaderData
190190
#define HEAP_HASNULL 0x0001 /* has null attribute(s) */
191191
#define HEAP_HASVARWIDTH 0x0002 /* has variable-width attribute(s) */
192192
#define HEAP_HASEXTERNAL 0x0004 /* has external stored attribute(s) */
193-
#define HEAP_HASROWID 0x0008 /* has an ROWID field */
193+
#define HEAP_HASROWID 0x0008 /* has a ROWID field */
194194
#define HEAP_XMAX_KEYSHR_LOCK 0x0010 /* xmax is a key-shared locker */
195195
#define HEAP_COMBOCID 0x0020 /* t_cid is a combo CID */
196196
#define HEAP_XMAX_EXCL_LOCK 0x0040 /* xmax is exclusive locker */

src/oracle_test/regress/sql/ora_rowid.sql

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
--
2-
-- Test Compatible Oracle ROWID pseudo
2+
-- Test Oracle-Compatible ROWID Pseudo-Column
33
--
44

55
--
@@ -111,12 +111,12 @@ alter table t2 set without rowid;
111111

112112
select (rowid).rowno, * from t2;
113113

114-
-- clearup
114+
-- cleanup
115115
drop table t2;
116116
drop table t3;
117117

118118
--
119-
--3, CTEATE TABLE ... WITH ROWID
119+
--3, CREATE TABLE ... WITH ROWID
120120
--
121121
create table t2 (a int, b int) with rowid;
122122

0 commit comments

Comments
 (0)