1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
/*-------------------------------------------------------------------------
*
* not_in.c
* Executes the "not_in" operator for any data type
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/not_in.c,v 1.15 1999/03/15 03:24:32 tgl Exp $
*
*-------------------------------------------------------------------------
*/
/*
*
* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
* X HACK WARNING!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! X
* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
*
* This code is the OLD not-in code that is HACKED
* into place until operators that can have arguments as
* columns are ******REALLY****** implemented!!!!!!!!!!!
*
*/
#include <stdio.h>
#include <string.h>
#include "postgres.h"
#include "access/heapam.h"
#include "access/relscan.h"
#include "utils/builtins.h" /* where function decls go */
static int my_varattno(Relation rd, char *a);
/* ----------------------------------------------------------------
*
* ----------------------------------------------------------------
*/
bool
int4notin(int32 not_in_arg, char *relation_and_attr)
{
Relation relation_to_scan;
int32 integer_value;
HeapTuple current_tuple;
HeapScanDesc scan_descriptor;
bool dummy,
retval;
int attrid;
char *relation,
*attribute;
char my_copy[NAMEDATALEN*2+2];
Datum value;
strncpy(my_copy, relation_and_attr, sizeof(my_copy));
my_copy[sizeof(my_copy)-1] = '\0';
relation = (char *) strtok(my_copy, ".");
attribute = (char *) strtok(NULL, ".");
if (attribute == NULL)
{
elog(ERROR, "int4notin: must provide relationname.attributename");
}
/* Open the relation and get a relation descriptor */
relation_to_scan = heap_openr(relation);
if (!RelationIsValid(relation_to_scan))
{
elog(ERROR, "int4notin: unknown relation %s",
relation);
}
/* Find the column to search */
attrid = my_varattno(relation_to_scan, attribute);
if (attrid < 0)
{
elog(ERROR, "int4notin: unknown attribute %s for relation %s",
attribute, relation);
}
scan_descriptor = heap_beginscan(relation_to_scan, false, SnapshotNow,
0, (ScanKey) NULL);
retval = true;
/* do a scan of the relation, and do the check */
while (HeapTupleIsValid(current_tuple = heap_getnext(scan_descriptor, 0)))
{
value = heap_getattr(current_tuple,
(AttrNumber) attrid,
RelationGetDescr(relation_to_scan),
&dummy);
integer_value = DatumGetInt32(value);
if (not_in_arg == integer_value)
{
retval = false;
break; /* can stop scanning now */
}
}
/* close the relation */
heap_close(relation_to_scan);
return retval;
}
bool
oidnotin(Oid the_oid, char *compare)
{
if (the_oid == InvalidOid)
return false;
return int4notin(the_oid, compare);
}
/*
* XXX
* If varattno (in parser/catalog_utils.h) ever is added to
* cinterface.a, this routine should go away
*/
static int
my_varattno(Relation rd, char *a)
{
int i;
for (i = 0; i < rd->rd_rel->relnatts; i++)
{
if (!namestrcmp(&rd->rd_att->attrs[i]->attname, a))
return i + 1;
}
return -1;
}
|