30
30
#include " ../dsql/errd_proto.h"
31
31
#include " ../dsql/gen_proto.h"
32
32
#include " ../dsql/make_proto.h"
33
+ #include " ../dsql/metd_proto.h"
33
34
#include " ../dsql/pass1_proto.h"
35
+ #include < unordered_set>
34
36
35
37
using namespace Firebird ;
36
38
using namespace Jrd ;
@@ -72,7 +74,7 @@ void DsqlCompilerScratch::qualifyNewName(QualifiedName& name) const
72
74
}
73
75
}
74
76
75
- void DsqlCompilerScratch::qualifyExistingName (QualifiedName& name, ObjectType objectType )
77
+ void DsqlCompilerScratch::qualifyExistingName (QualifiedName& name, std::initializer_list< ObjectType> objectTypes )
76
78
{
77
79
if (!(name.schema .isEmpty () && name.object .hasData ()))
78
80
return ;
@@ -96,10 +98,123 @@ void DsqlCompilerScratch::qualifyExistingName(QualifiedName& name, ObjectType ob
96
98
}
97
99
}
98
100
99
- attachment->qualifyExistingName (tdbb, name, objectType , cachedDdlSchemaSearchPath);
101
+ attachment->qualifyExistingName (tdbb, name, objectTypes , cachedDdlSchemaSearchPath);
100
102
}
101
103
else
102
- attachment->qualifyExistingName (tdbb, name, objectType);
104
+ attachment->qualifyExistingName (tdbb, name, objectTypes);
105
+ }
106
+
107
+
108
+ std::variant<std::monostate, dsql_prc*, dsql_rel*, dsql_udf*> DsqlCompilerScratch::resolveRoutineOrRelation (
109
+ QualifiedName& name, std::initializer_list<ObjectType> objectTypes)
110
+ {
111
+ const std::unordered_set<ObjectType> objectTypesSet (objectTypes);
112
+ const bool searchProcedures = objectTypesSet.find (obj_procedure) != objectTypesSet.end ();
113
+ const bool searchRelations = objectTypesSet.find (obj_relation) != objectTypesSet.end ();
114
+ const bool searchFunctions = objectTypesSet.find (obj_udf) != objectTypesSet.end ();
115
+ fb_assert ((searchProcedures || searchRelations) != searchFunctions);
116
+
117
+ std::variant<std::monostate, dsql_prc*, dsql_rel*, dsql_udf*> object;
118
+
119
+ const auto notFound = [&]()
120
+ {
121
+ return std::holds_alternative<std::monostate>(object);
122
+ };
123
+
124
+ const auto setObject = [&](const auto value)
125
+ {
126
+ if (value)
127
+ object = value;
128
+ };
129
+
130
+ // search subroutine: name
131
+ if (name.schema .isEmpty () &&
132
+ name.package .isEmpty ())
133
+ {
134
+ if (searchProcedures)
135
+ {
136
+ if (const auto subProcedure = getSubProcedure (name.object ))
137
+ setObject (subProcedure->dsqlProcedure );
138
+ }
139
+
140
+ if (searchFunctions)
141
+ {
142
+ if (const auto subFunction = getSubFunction (name.object ))
143
+ setObject (subFunction->dsqlFunction );
144
+ }
145
+ }
146
+
147
+ // search packaged routine in the same package: name, same_package.name
148
+ if (notFound () &&
149
+ package.object .hasData () &&
150
+ name.package .isEmpty () &&
151
+ (name.schema .isEmpty () ||
152
+ (!name.isUnambiguous () && name.schema == package.object )))
153
+ {
154
+ const QualifiedName routineName (name.object , package.schema , package.object );
155
+
156
+ if (searchProcedures)
157
+ setObject (METD_get_procedure (getTransaction (), this , routineName));
158
+
159
+ if (searchFunctions)
160
+ setObject (METD_get_function (getTransaction (), this , routineName));
161
+ }
162
+
163
+ // search standalone routine or relation: name, name1%schema.name2, name1.name2
164
+ if (notFound () &&
165
+ name.package .isEmpty ())
166
+ {
167
+ auto qualifiedName = name;
168
+ qualifyExistingName (qualifiedName, objectTypes);
169
+
170
+ if (searchProcedures)
171
+ setObject (METD_get_procedure (getTransaction (), this , qualifiedName));
172
+
173
+ if (searchRelations)
174
+ setObject (METD_get_relation (getTransaction (), this , qualifiedName));
175
+
176
+ if (searchFunctions)
177
+ setObject (METD_get_function (getTransaction (), this , qualifiedName));
178
+ }
179
+
180
+ // search packaged routine: name1%package.name2, name1.name2.name3
181
+ if (notFound () &&
182
+ name.package .hasData ())
183
+ {
184
+ auto qualifiedName = name;
185
+ qualifyExistingName (qualifiedName, objectTypes);
186
+
187
+ if (searchProcedures)
188
+ setObject (METD_get_procedure (getTransaction (), this , qualifiedName));
189
+
190
+ if (searchFunctions)
191
+ setObject (METD_get_function (getTransaction (), this , qualifiedName));
192
+ }
193
+
194
+ // search packaged routine: name1.name2
195
+ if (notFound () &&
196
+ !name.isUnambiguous () &&
197
+ name.schema .hasData () &&
198
+ name.package .isEmpty ())
199
+ {
200
+ QualifiedName qualifiedName (name.object , {}, name.schema );
201
+ qualifyExistingName (qualifiedName, objectTypes);
202
+
203
+ if (searchProcedures)
204
+ setObject (METD_get_procedure (getTransaction (), this , qualifiedName));
205
+
206
+ if (searchFunctions)
207
+ setObject (METD_get_function (getTransaction (), this , qualifiedName));
208
+ }
209
+
210
+ if (const auto procedure = std::get_if<dsql_prc*>(&object))
211
+ name = (*procedure)->prc_name ;
212
+ else if (const auto relation = std::get_if<dsql_rel*>(&object))
213
+ name = (*relation )->rel_name ;
214
+ else if (const auto function = std::get_if<dsql_udf*>(&object))
215
+ name = (*function)->udf_name ;
216
+
217
+ return object;
103
218
}
104
219
105
220
0 commit comments