-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[GAIAPLAT-672] Implement connect/disconnect translation in gaiat #841
Conversation
This reverts commit 49bbe9a.
…into rondelli-conn-disconn-gaiat-2
…-conn-disconn-gaiat-2
…into rondelli-conn-disconn-gaiat-2
@@ -3025,6 +3028,140 @@ class declarative_break_continue_handler_t : public MatchFinder::MatchCallback | |||
Rewriter& m_rewriter; | |||
}; | |||
|
|||
// AST handler that is called when declarative break or continue are used in the rule. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Whoopsy.
{ | ||
// Changes connect() to insert() for 1:N relationships. | ||
// TODO https://gaiaplatform.atlassian.net/browse/GAIAPLAT-1181 | ||
m_rewriter.ReplaceText(method_call_expr->getExprLoc(), c_connect_length, "insert"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you have full EDC support for this and remove ? I.e. the spec says it should handle the cases when records already connected etc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point. This is supported in the 1:1 connect disconnect (at EDC level) but not for 1:n. I would implement this in EDC to make the 2 APIs somewhat symmetric.
Created a task for it: https://gaiaplatform.atlassian.net/browse/GAIAPLAT-1193
method_call_expr->getExprLoc().getLocWithOffset(c_disconnect_length + 1), | ||
method_call_expr->getEndLoc()); | ||
|
||
param_loc.dump(*result.SourceManager); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You don't need this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Damn, forgot it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have no special observations. The logic should be reviewed by Greg.
auto src_table_iter = table_data.find(src_table_name); | ||
if (src_table_iter == table_data.end()) | ||
{ | ||
cerr << "Table '" << src_table_name << "' was not found in the catalog." << endl; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd like to check in my changes before yours and then you can pick up the error strings. Ideally there is one you can use like err_table_not_found
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've pushed to master. Thanks!
@@ -56,6 +56,9 @@ bool g_is_rule_prolog_specified = false; | |||
constexpr int c_encoding_shift = 16; | |||
constexpr int c_encoding_mask = 0xFFFF; | |||
|
|||
constexpr size_t c_connect_length = 7; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: maybe c_connect_keyword_length
would be more descriptive.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
@@ -3025,6 +3028,140 @@ class declarative_break_continue_handler_t : public MatchFinder::MatchCallback | |||
Rewriter& m_rewriter; | |||
}; | |||
|
|||
// AST handler that is called when declarative break or continue are used in the rule. | |||
class declarative_connect_disconnect_handler_t : public MatchFinder::MatchCallback |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does it make sense to break this up into two handlers? (connect handler and disconnect handler)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's what I started with until I realized that the code is 95% the same. An alternative would be to have a parent class that handles all the common logic and subclasses with specializations.
I can go down this route if you wish.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, parent class or a helper function that both call. Just then you wouldn't have to check which keyword it is "connect" or "disconnect" and the two cases are different. I don't mind having single-purpose matchers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, when we are going to add connect/disconnect to the EDC containers the code will be exactly the same.
bool need_link_field = false; | ||
|
||
const auto* method_call_expr = result.Nodes.getNodeAs<CXXMemberCallExpr>("connectDisconnectCall"); | ||
bool is_connect = method_call_expr->getMethodDecl()->getName().str() == "connect"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Someday I'd like to consolidate all our declarative language keywords into a single string table... (not saying you should do this now, but maybe move the string to a c_connect_keyword
constant.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but maybe move the string to a c_connect_keyword constant.
Done.
|
||
if (link_name.empty()) | ||
{ | ||
cerr << "Impossible to find a link between table " << src_table_name << " and table " << dest_table_name << endl; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
consider rewording from "Impossible to ..." to something like "A link does not exist between ...". Then add to DiagnosticSemaKinds.td (in alphabetical order) where our Gaia errors are at the bottom of the file grouped by err, note, and warn. Then use the gaiat::diag().emit(...)
construct to report an LLVM error. Of course, these changes will only be visible after I merge PR-820.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
consider rewording from "Impossible to ..." to something like "A link does not exist between ...". T
Done.
WIll do the rest after you merge your PR.
production/tools/gaia_translate/tests/test_connect_disconnect.cpp
Outdated
Show resolved
Hide resolved
|
||
TEST_F(test_connect_disconnect, test_connect_1_n) | ||
{ | ||
gaia::rules::initialize_rules_engine(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like these two lines (init rules engine and unsubscribe) are used in every test. Consider moving to Setup
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. @waynelwarren can we do the same for other tests?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I can take a look at this.
|
||
using namespace gaia::barn_storage; | ||
|
||
ruleset test_connect_disconnect |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
probably handled below but why no disconnect
rule/test here? I feel misled by the ruleset name :).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should not be here, removed. We squeeze all the tests into one ruleset, and then we create different tests files for each type of test. This greatly improves compile time.
third_party/production/TranslationEngineLLVM/clang/lib/Sema/SemaGaia.cpp
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mostly nits and a confusion about the integration tests. Cool to see this functionality almost in!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. I have built and tested this branch. Added one small test.
* simple new disconnect/remove test * using size() method rather than scanning members
@@ -9526,7 +9526,7 @@ def err_duplicate_field : Error< | |||
"Duplicate field '%0' found in table '%1'. Qualify your field with the " | |||
"table name (table.field) to disambiguate field names that occur in more " | |||
"than one table. You can also restrict the list of tables to search by " | |||
"specifing them in the ruleset 'tables' attribute.">; | |||
"specifying them in the ruleset 'tables' attribute.">; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch. Thanks!
@@ -9578,8 +9578,6 @@ def err_invalid_parent_table : Error< | |||
"Incorrect parent table in the relationship '%0'.">; | |||
def err_invalid_table_field : Error< | |||
"Field '%0' has no table in the catalog.">; | |||
def err_invalid_table_name : Error< |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't need this error any more? Ah, I guess this was a dup with err_table_not_found
. Another good catch.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep. This is subsumed by err_table_not_found
.
@@ -70,7 +70,7 @@ ruleset test38 | |||
|
|||
ruleset test39 | |||
{ | |||
on_update(value) // expected-error {{Duplicate field 'value' found in table 'actuator'. Qualify your field with the table name (table.field) to disambiguate field names that occur in more than one table. You can also restrict the list of tables to search by specifing them in the ruleset 'tables' attribute.}} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
😭 Thank you for fixing this up for me. Embarrassing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good.
Add the connect/disconnect handling logic in gaiat.
declarative_connect_disconnect_handler_t
in gaiat + relative matchers.table.link.disconnect()
. Link name must be specified and no arguments required.GaiaTable
attribute to add to the classes that represent tables in the DB.err_invalid_table_name
message because it is a duplicate oferr_table_not_found
.link_data_t
totable_data_t
intable_navigation.h