aboutsummaryrefslogtreecommitdiff
path: root/pkg/utilities/nttools/tjoin/issame.x
blob: 89ea221d61ddb3dab2c6d1266703020b09d9e872 (plain) (blame)
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
include "tjoin.h"

# B.Simon	16-Apr-99	first code

# IS_SAME -- See if two values in different tables are the same

bool procedure is_same (tj1, tj2, irow, jrow, tol, casesens)

pointer	tj1	    # i: Table info descriptor for first input table
pointer	tj2	    # i: Table info descriptor for second input table
int	irow	    # i: Row number of element in first table
int	jrow	    # i: Row number of element in second table
pointer	tol	    # i: Descriptor of vecor of tolerance values
bool    casesens    # i: Join is case sensitive
#--
bool	same
double	dval1, dval2
int	icol, dtype1, dtype2, ival1, ival2
pointer	sp, str1, str2

string	badtol   "Tolerance must be zero for joins on non-numeric columns"
string	badtype  "Type mismatch on join columns"

bool	streq()
int	spp_type()

begin
	# Allocate memory for table strings

	call smark (sp)
	call salloc (str1, SZ_LINE, TY_CHAR)
	call salloc (str2, SZ_LINE, TY_CHAR)

	same = true
	do icol = 1, TJ_JNUM(tj1) {
	    if (! same)
		break

	    # Get column data types

	    dtype1 = spp_type (TJ_JCOL(tj1,icol))
	    dtype2 = spp_type (TJ_JCOL(tj2,icol))

	    # Comparison depends on data type

	    if (dtype1 == TY_CHAR && dtype2 == TY_CHAR) {
		# Nonzero tolerance illegal on string columns

		if (TOL_VAL(tol,icol) != 0.0)
		    call error (1, badtol)

		call tbegtt (TJ_TAB(tj1), TJ_JCOL(tj1,icol), irow, 
			     Memc[str1], SZ_LINE)
		call tbegtt (TJ_TAB(tj2), TJ_JCOL(tj2,icol), jrow, 
			     Memc[str2], SZ_LINE)

		# Convert to lower case for case insensitive match

		if (! casesens) {
		    call strlwr (Memc[str1])
		    call strlwr (Memc[str2])
		}

		# Test for undefined values first, which never match

		if (Memc[str1] == EOS || Memc[str2] == EOS) {
		    same = false
		} else {
		    same = streq (Memc[str1], Memc[str2])
		}

	    } else if (dtype1 == TY_BOOL && dtype2 == TY_BOOL) {
		# Nonzero tolerance illegal on boolean column

		if (TOL_VAL(tol,icol) != 0.0)
		    call error (1, badtol)

		# Read boolean as integer so we can detect undefined values

		call tbegti (TJ_TAB(tj1), TJ_JCOL(tj1,icol), irow, ival1)
		call tbegti (TJ_TAB(tj2), TJ_JCOL(tj2,icol), jrow, ival2)

		# Undefined values never match anything

		if (IS_INDEFI(ival1) || IS_INDEFI(ival2)) {
		    same = false
		} else {
		    same = ival1 == ival2
		}

	    } else if (dtype1 == TY_CHAR || dtype1 == TY_BOOL ||
		       dtype2 == TY_BOOL || dtype2 == TY_BOOL) {

		# Catch comparison of numeric and non-numeric values

		call error (1, badtype)

	    } else {
		# Null column pointer indicates the join is done on row number

		if (TJ_JCOL(tj1,icol) == NULL) {
		    dval1 = irow
		} else {
		    call tbegtd (TJ_TAB(tj1), TJ_JCOL(tj1,icol), irow, dval1)
		}

		if (TJ_JCOL(tj2,icol) == NULL) {
		    dval2 = jrow
		} else {
		    call tbegtd (TJ_TAB(tj2), TJ_JCOL(tj2,icol), jrow, dval2)
		}

		# Undefined values never match
		# Numeric values must be checked to see if the
		# difference is smaller than the tolerance

		if (IS_INDEFD(dval1) || IS_INDEFD(dval2)) {
		    same = false
		} else {
		    same = abs (dval2 - dval1) <= TOL_VAL(tol,icol)
		}
	    }
	}

	call sfree (sp)
	return (same)
end