Skip to content

Conversation

@andsel
Copy link
Contributor

@andsel andsel commented Nov 25, 2019

Add the support to prepared statements in local_lookup solves #50

@elasticsearch-bot elasticsearch-bot self-assigned this Nov 25, 2019
returns multiple columns, the data is stored as a JSON object within the field.
<5> Takes data from the JSON object and stores it in top-level event fields for
easier analysis in Kibana.
<6> Local lookup queries could be use also prepared statements.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Local lookup queries could also use prepared statements."
... but @karenzone should double check on us 😉

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about, "Local lookup queries can also use prepared statements."?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like it more, thanks

begin
logger.debug? && logger.debug("Executing Jdbc query", :lookup_id => @id, :statement => query, :parameters => params)
@prepared_statement.call(params).each do |row|
stringified = row.inject({}){|hash,(k,v)| hash[k.to_s] = v; hash} #Stringify row keys
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Q: why do we need to stringify (just curious) ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've taken suggestion from the no prepared part, I think the stringify is need to avoid errors of type conversion error when the JDBC driver loads a BigInteger or the driver does ugly conversions.

A SQL SELECT statement that is executed to achieve the lookup. To use
parameters, use named parameter syntax, for example
`"SELECT * FROM MYTABLE WHERE ID = :id"`.
`"SELECT * FROM MYTABLE WHERE ID = :id"`. Alternatively could be also use
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Alternatively the ? sign could be used as prepared statement parameters, in which case the prepared_parameters is used to populate the values."
(maybe "... provide the values") sounds better - not sure.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about, "Alternatively, the ? sign can be used as a prepared statement parameter, in which case the prepared_parameters array is used to populate the values

Copy link
Contributor

@karenzone karenzone left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The callout list is rendering incorrectly. I will research.

returns multiple columns, the data is stored as a JSON object within the field.
<5> Takes data from the JSON object and stores it in top-level event fields for
easier analysis in Kibana.
<6> Local lookup queries could be use also prepared statements.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about, "Local lookup queries can also use prepared statements."?

returns multiple columns, the data is stored as a JSON object within the field.
<5> Takes data from the JSON object and stores it in top-level event fields for
easier analysis in Kibana.
<6> Local lookup queries could be use also prepared statements.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The callout list is acting up for no obvious reason. I will figure out why.

Screen Shot 2019-11-25 at 10 32 27 AM

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@karenzone Is this an issue with out of order callouts? The <6> is defined before the <5> and I seem to recall that callouts are auto-numbered(?), and ignored the number given in the table other than as a label to refer back to

Copy link
Contributor

@karenzone karenzone Nov 25, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, @robbavey. You are correct!
@andsel The callouts must be issued in numerical order. Also, since our conversion to asciidoctor, we can't reuse a number (see <5> and <5>, for example). In other words, what was there worked before we converted to asciidoctor. It hasn't been quite right since we converted. (The repeated number is not related to any work you did.) Please let me know if you have questions.
Screen Shot 2019-11-25 at 4 48 05 PM

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you want entries for both <5>, you can define once and assume the user will get it. Or, you can define as <5> and <6>, and reorder the other items accordingly.

As long as you define your callouts in order in your code sample, and don't repeat numbers, you should be fine.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@karenzone I've fixed the number ordering, but I don't know how to fix the issue related to double use of same callout

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@andsel @karenzone How about having a single callout in the comment above the add_field settings - I'm not quite sure why the docs originally only had callouts on two of the three add_field, and putting it in the comment might work as a way of grouping the settings

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with you, and I would add the callout to the first of the add_field definitions

A SQL SELECT statement that is executed to achieve the lookup. To use
parameters, use named parameter syntax, for example
`"SELECT * FROM MYTABLE WHERE ID = :id"`.
`"SELECT * FROM MYTABLE WHERE ID = :id"`. Alternatively could be also use
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about, "Alternatively, the ? sign can be used as a prepared statement parameter, in which case the prepared_parameters array is used to populate the values

let(:local_db) { double("local_db") }
let(:lookup_hash) do
{
"query" => "select * from servers WHERE ip LIKE ?",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we have a test with >1 parameters?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, thanks for suggestion, because spotted a test that didn'tt do its job:-)

@robbavey
Copy link
Member

@andsel, @jsvd I think this is a nicely done PR, with my only issue being a nagging question as to whether we need to expose this option to the user - given that the Derby database used for local lookups is somewhat an implementation detail, and we are asking the user to understand this implementation detail to determine whether or not to use prepared statements.

If we do expose this detail, we should probably document that the use of prepared statements in this plugin is preferred.
(I do realise that they way we currently use queries and parameters complicates this question somewhat)

@andsel
Copy link
Contributor Author

andsel commented Nov 26, 2019

@robbavey I think we expose the concept that the local DB could use prepared statements, not really an internal detail of Derby. But your point is correct, if we prefer the prepared statements we should avoid or discourage the use of the normal statements, but we can't drop that support because it's already used by pipelines out in the wild

@robbavey
Copy link
Member

@andsel I'm ok with that - if we add a documentation note that the use of prepared statements is preferred/encouraged, and explain the reasons why, then I think this is good

cc @karenzone

Copy link
Member

@robbavey robbavey left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nearly there, I think - can we add an integration test, and an "abnormal operation" test?

Also, there a few leftover debug statements that should be removed before merging.

parameters => {id => "[loggedin_userid]"}
target => "user" <4>
query => "select firstname, lastname from users WHERE userid = ?"
prepared_parameters => ["[loggedin_userid]"] <4>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about having an example with > 1 prepared_parameters? There could be confusion as to what the correct syntax here (is it ["[param1, param2]"] or ["[param1]", "[param2]"]? Or does it not matter?) It might also help to reiterate here that the order of the parameters in prepared_parameters is important

end

def fetch(local, event)
puts "Lookup::fetch >> invoked"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Leftover debug statement?

end

def call_prepared(local, event)
puts "Lookup::call_prepared >> invoked"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Leftover debug statement?

begin
logger.debug? && logger.debug("Executing Jdbc query", :lookup_id => @id, :statement => query, :parameters => params)
@prepared_statement.call(params).each do |row|
puts "Lookup::call_prepared >> retrieved rw: #{row}"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Leftover debug statement?

@andsel andsel requested a review from robbavey November 26, 2019 16:15
@karenzone karenzone self-requested a review November 26, 2019 17:51
Copy link
Contributor

@karenzone karenzone left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Docs build cleanly and render properly. Docs LGTM.

Copy link
Member

@robbavey robbavey left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Getting very close, just an integration test failure to fix, and I think given that we are introducing a new feature, we should be incrementing the minor of the plugin, rather than just the patch.

CHANGELOG.md Outdated
@@ -1,3 +1,6 @@
## 1.0.8
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe change this to a minor upgrade, as we are adding a new feature.

Gem::Specification.new do |s|
s.name = 'logstash-filter-jdbc_static'
s.version = '1.0.7'
s.version = '1.0.8'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe change this to a minor upgrade, as we are adding a new feature.

context "under normal conditions with prepared statement" do
let(:lookup_statement) { "SELECT * FROM servers WHERE ip LIKE ?" }
it "enhances an event" do
settings.local_lookups.prepared_parameters = [parameters_rhs]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This currently fails testing - https://travis-ci.org/logstash-plugins/logstash-filter-jdbc_static/builds/617288523

To replace the value of parameters with prepared_parameters for this test case, I think you will need to replace the whole local_lookups block in :settings, rather than just the lookup statement: you will need to remove the existing parameters setting as well as include a new prepared_parameters setting.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done :-) thanks @robbavey now Travis is green

Copy link
Member

@robbavey robbavey left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Nice job @andsel

@andsel andsel force-pushed the feature/support_prepared_statements branch from 9aea0d0 to 91432a8 Compare November 27, 2019 08:17
@elasticsearch-bot
Copy link

Andrea Selva merged this into the following branches!

Branch Commits
master 02c9ec2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants