Line data Source code
1 : /*
2 : * SPDX-License-Identifier: MPL-2.0
3 : *
4 : * This Source Code Form is subject to the terms of the Mozilla Public
5 : * License, v. 2.0. If a copy of the MPL was not distributed with this
6 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
7 : *
8 : * Copyright 2024 MonetDB Foundation;
9 : * Copyright August 2008 - 2023 MonetDB B.V.;
10 : * Copyright 1997 - July 2008 CWI.
11 : */
12 :
13 : #include "monetdb_config.h"
14 : #include "sql_relation.h"
15 : #include "rel_prop.h"
16 : #include "sql_string.h"
17 : #include "sql_atom.h"
18 :
19 : prop *
20 19949714 : prop_create( allocator *sa, rel_prop kind, prop *pre )
21 : {
22 19949714 : prop *p = SA_NEW(sa, prop);
23 :
24 19949627 : *p = (prop) {
25 : .kind = kind,
26 : .p = pre,
27 : };
28 19949627 : if (kind == PROP_NUNIQUES)
29 19949627 : p->value.dval = 0.0; /* floating point compatibility */
30 19949627 : return p;
31 : }
32 :
33 : prop *
34 9765798 : prop_copy( allocator *sa, prop *p )
35 : {
36 9765798 : prop *np = NULL;
37 :
38 18796168 : for(; p; p = p->p) {
39 9030369 : np = prop_create(sa, p->kind, np);
40 9030370 : np->id = p->id;
41 9030370 : switch (p->kind) {
42 4 : case PROP_COUNT:
43 4 : np->value.lval = p->value.lval;
44 4 : break;
45 3451022 : case PROP_NUNIQUES:
46 3451022 : np->value.dval = p->value.dval;
47 3451022 : break;
48 5579344 : default:
49 5579344 : np->value.pval = p->value.pval;
50 : }
51 : }
52 9765799 : return np;
53 : }
54 :
55 : prop *
56 676 : prop_remove( prop *plist, prop *p )
57 : {
58 676 : prop *op = plist;
59 :
60 676 : if (plist == p)
61 633 : return p->p;
62 43 : for(; op; op = op->p) {
63 39 : if (op->p == p) {
64 39 : op->p = p->p;
65 39 : break;
66 : }
67 : }
68 : return plist;
69 : }
70 :
71 : prop *
72 33503332 : find_prop( prop *p, rel_prop kind)
73 : {
74 59237404 : while(p) {
75 38754654 : if (p->kind == kind)
76 13020582 : return p;
77 25734072 : p = p->p;
78 : }
79 : return p;
80 : }
81 :
82 : void *
83 13224831 : find_prop_and_get(prop *p, rel_prop kind)
84 : {
85 13224831 : prop *found = find_prop(p, kind);
86 :
87 : /* this doesn't work with numbers yet */
88 13224833 : assert(kind != PROP_COUNT && kind != PROP_NUNIQUES);
89 13224833 : return found ? found->value.pval : NULL;
90 : }
91 :
92 : #ifdef MIN
93 : #undef MIN
94 : #endif
95 :
96 : #ifdef MAX
97 : #undef MAX
98 : #endif
99 :
100 : const char *
101 490 : propkind2string( prop *p)
102 : {
103 490 : switch(p->kind) {
104 : #define PT(TYPE) case PROP_##TYPE : return #TYPE
105 : PT(COUNT);
106 0 : PT(NUNIQUES);
107 63 : PT(JOINIDX);
108 1 : PT(HASHIDX);
109 414 : PT(HASHCOL);
110 12 : PT(REMOTE);
111 0 : PT(USED);
112 0 : PT(GROUPINGS);
113 0 : PT(MIN);
114 0 : PT(MAX);
115 : }
116 0 : return "UNKNOWN";
117 : }
118 :
119 : char *
120 490 : propvalue2string(allocator *sa, prop *p)
121 : {
122 490 : char buf [BUFSIZ];
123 :
124 490 : switch(p->kind) {
125 0 : case PROP_COUNT: {
126 0 : snprintf(buf, BUFSIZ, BUNFMT, p->value.lval);
127 0 : return sa_strdup(sa, buf);
128 : }
129 0 : case PROP_NUNIQUES: {
130 0 : snprintf(buf, BUFSIZ, "%f", p->value.dval);
131 0 : return sa_strdup(sa, buf);
132 : }
133 63 : case PROP_JOINIDX: {
134 63 : sql_idx *i = p->value.pval;
135 :
136 63 : if (i) {
137 63 : snprintf(buf, BUFSIZ, "\"%s\".\"%s\".\"%s\"", sql_escape_ident(sa, i->t->s->base.name),
138 63 : sql_escape_ident(sa, i->t->base.name), sql_escape_ident(sa, i->base.name));
139 63 : return sa_strdup(sa, buf);
140 : }
141 : } break;
142 12 : case PROP_REMOTE: {
143 12 : list *tids_uris = p->value.pval;
144 12 : if (!list_empty(tids_uris)) {
145 12 : size_t offset = 0;
146 24 : for (node *n = ((list*)p->value.pval)->h; n; n = n->next) {
147 12 : tid_uri *tu = n->data;
148 12 : if (tu->uri)
149 24 : offset += snprintf(buf + offset, BUFSIZ, "%s%s",
150 : sql_escape_ident(sa, offset?" ":""),
151 : sql_escape_ident(sa, tu->uri));
152 : }
153 12 : return sa_strdup(sa, buf);
154 : }
155 : } break;
156 0 : case PROP_MIN:
157 : case PROP_MAX: {
158 0 : atom *a = p->value.pval;
159 0 : char *res = NULL;
160 :
161 0 : if (a->isnull) {
162 0 : res = sa_strdup(sa, "\"NULL\"");
163 : } else {
164 0 : char *s = ATOMformat(a->data.vtype, VALptr(&a->data));
165 0 : if (s && *s == '"') {
166 0 : res = sa_strdup(sa, s);
167 0 : } else if (s) {
168 0 : res = sa_alloc(sa, strlen(s) + 3);
169 0 : stpcpy(stpcpy(stpcpy(res, "\""), s), "\"");
170 : }
171 0 : GDKfree(s);
172 : }
173 : return res;
174 : }
175 : default:
176 : break;
177 : }
178 415 : return sa_strdup(sa, "");
179 : }
|