MCPcopy Create free account
hub / github.com/FirebirdSQL/firebird / internalDsqlPass

Method internalDsqlPass

src/dsql/ExprNodes.cpp:6071–6369  ·  view source on GitHub ↗

Resolve a field name to an available context. If list is true, then this function can detect and return a relation node if there is no name. This is used for cases of "SELECT . ...". CVC: The function attempts to detect if an unqualified field appears in more than one context and hence it returns the number of occurrences. This was added to allow the caller to detect ambiguous commands

Source from the content-addressed store, hash-verified

6069// ambiguous commands like select from t1 join t2 on t1.f = t2.f order by common_field.
6070// While inoffensive on inner joins, it changes the result on outer joins.
6071ValueExprNode* FieldNode::internalDsqlPass(DsqlCompilerScratch* dsqlScratch, RecordSourceNode** list)
6072{
6073 thread_db* tdbb = JRD_get_thread_data();
6074
6075 if (list)
6076 *list = NULL;
6077
6078 /* CVC: PLEASE READ THIS EXPLANATION IF YOU NEED TO CHANGE THIS CODE.
6079 You should ensure that this function:
6080 1.- Never returns NULL. In such case, it such fall back to an invocation
6081 to PASS1_field_unknown() near the end of this function. None of the multiple callers
6082 of this function (inside this same module) expect a null pointer, hence they
6083 will crash the engine in such case.
6084 2.- Doesn't allocate more than one field in "node". Either you put a break,
6085 keep the current "continue" or call ALLD_release if you don't want nor the
6086 continue neither the break if node is already allocated. If it isn't evident,
6087 but this variable is initialized to zero in the declaration above. You
6088 may write an explicit line to set it to zero here, before the loop.
6089
6090 3.- Doesn't waste cycles if qualifier is not null. The problem is not the cycles
6091 themselves, but the fact that you'll detect an ambiguity that doesn't exist: if
6092 the field appears in more than one context but it's always qualified, then
6093 there's no ambiguity. There's PASS1_make_context() that prevents a context's
6094 alias from being reused. However, other places in the code don't check that you
6095 don't create a join or subselect with the same context without disambiguating it
6096 with different aliases. This is the place where resolveContext() is called for
6097 that purpose. In the future, it will be fine if we force the use of the alias as
6098 the only allowed qualifier if the alias exists. Hopefully, we will eliminate
6099 some day this construction: "select table.field from table t" because it
6100 should be "t.field" instead.
6101
6102 AB: 2004-01-09
6103 The explained query directly above doesn't work anymore, thus the day has come ;-)
6104 It's allowed to use the same fieldname between different scope levels (sub-queries)
6105 without being hit by the ambiguity check. The field uses the first match starting
6106 from it's own level (of course ambiguity-check on each level is done).
6107
6108 4.- Doesn't verify code derived automatically from check constraints. They are
6109 ill-formed by nature but making that code generation more orthodox is not a
6110 priority. Typically, they only check a field against a contant. The problem
6111 appears when they check a field against a subselect, for example. For now,
6112 allow the user to write ambiguous subselects in check() statements.
6113 Claudio Valderrama - 2001.1.29.
6114 */
6115
6116 // Try to resolve field against various contexts;
6117 // if there is an alias, check only against the first matching
6118
6119 ValueExprNode* node = NULL; // This var must be initialized.
6120 DsqlContextStack ambiguousCtxStack;
6121
6122 bool resolveByAlias = true;
6123 const bool relaxedAliasChecking = Config::getRelaxedAliasChecking();
6124
6125 while (true)
6126 {
6127 // AB: Loop through the scope_levels starting by its own.
6128 bool done = false;

Callers 4

dsqlPassMethod · 0.45
PASS1_expand_select_nodeFunction · 0.45
pass1_group_by_listFunction · 0.45
PASS1_sortFunction · 0.45

Calls 15

JRD_get_thread_dataFunction · 0.85
ProcedureSourceNodeClass · 0.85
MAKE_fieldFunction · 0.85
ERRD_postFunction · 0.85
GdsClass · 0.85
NumClass · 0.85
PASS1_ambiguity_checkFunction · 0.85
PASS1_field_unknownFunction · 0.85
getImplicitJoinFieldMethod · 0.80
RelationSourceNodeClass · 0.70
hasDataMethod · 0.45
objectMethod · 0.45

Tested by

no test coverage detected