Re: [h2] Out of memory when Ordering results für very large table

2014-06-03 Thread Thomas Mueller
Hi,

I didn't run your test case, but just to let you know: ResultDiskTape will
not be used in future versions of H2. Instead, temporary tables are used.

Regards,
Thomas


On Monday, June 2, 2014,  wrote:

> Hi,
>
> I have already analyzed a heap dump with the software JProfiler.
>
> Please have a look at the function nextSorted() of class ResultDiskBuffer:
>
> *private* Value[] nextSorted() {
> *int* next = -1;
> *for* (*int* i = 0, size = tapes.size(); i < size; i++) {
> ResultDiskTape tape = tapes.get(i);
> *if* (tape.buffer.size() == 0 && tape.pos < tape.end) {
> file.seek(tape.pos);
> *for* (*int* j = 0; tape.pos < tape.end && j <
> *READ_AHEAD*; j++) {
> readRow(tape);
> }
> }
> *if* (tape.buffer.size() > 0) {
> *if* (next == -1) {
> next = i;
> } *else* *if* (compareTapes(tape, tapes.get(next)) < 0) {
> next = i;
> }
> }
> }
> ResultDiskTape t = tapes.get(next);
> Value[] row = t.buffer.get(0);
> t.buffer.remove(0);
> *return* row;
> }
>
> If I understood this correctly, then readRow() reads a row from the DB
> file into memory (ResultDiskTape.buffer).
> The for loop in the method above is not left until the next row (according
> to sort criteria) is found.
> So if finding takes many iterations, then many rows are held in memory -
> no matter which value is set for MAX_MEMORY_ROWS.
>
> Additionally, if I omit sorting (nextUnsorted() is called then), then
> fetching does NOT lead to out of memory errors.
>
> I wrote a simple java program for reproduction (creates a large table, and
> reads sorted/unsorted -- please run with -Xmx512m):
>
>
> *import* java.sql.Connection;
> *import* java.sql.DriverManager;
> *import* java.sql.PreparedStatement;
> *import* java.sql.ResultSet;
> *import* java.sql.SQLException;
> *import* java.sql.Statement;
> *import* java.util.Random;
>
>
> *public* *class* *H2OomFetch* {
> /**
>  * available synbols
>  */
> *private* *static* *char*[] *symbols*;
> /**
>  * Random number generator
>  */
> *private* *final* Random random = *new* Random();
>
> *static* {
> StringBuilder tmp = *new* StringBuilder();
> *for* (*char* ch = '0'; ch <= '9'; ++ch) {
> tmp.append(ch);
> }
> *for* (*char* ch = 'a'; ch <= 'z'; ++ch) {
> tmp.append(ch);
> }
> *symbols* = tmp.toString().toCharArray();
> }
>
> /**
>  * *@param* args Unused
>  */
> *public* *static* *void* main(String[] args){
> *try* {
> *new* H2OomFetch().run(5, 30, *true*); // ordered, leads
> to out of memory
> // new H2OomFetch().run(5, 30, false); // unordered, works
> } *catch* (Throwable t) {
> t.printStackTrace();
> }
> }
>
> /**
>  * Runs the test
>  * *@param* rows Number of rows
>  * *@param* cols Number of cols
>  * *@param* order true to order results
>  * *@throws* *SQLException*
>  */
> *private* *void* run(*int* rows, *int* cols, *boolean* order) *throws*
> SQLException {
> Connection connection = connect();
>
> Statement statement = connection.createStatement();
> statement.execute("set MAX_MEMORY_ROWS 10");
> *try* {
> statement.execute("drop table ordertest");
> } *catch* (SQLException ex) {
> // failed to drop, ignore
> }
> statement.execute(getCreateStatement(cols));
> statement.close();
>
> PreparedStatement insertStatement =
> connection.prepareStatement(getInsertStatement(cols));
> *for* (*int* row = 1;row <= rows; row++) {
> insertStatement.setInt(1, row);
> *for* (*int* i = 0; i < cols; i++) {
> insertStatement.setString(2 + i, getRandomString1K());
> }
> insertStatement.addBatch();
> *if* ((row % 20 == 0) || (row == rows)) {
> insertStatement.executeBatch();
> }
>
> *if* (row % 1000 == 0) {
> System.*out*.println("inserted " + row);
> }
> }
> connection.commit();
> statement = connection.createStatement();
> ResultSet rs = statement.executeQuery("select * from ordertest" +
> (order ? " order by ID DESC" : ""));
>
> *int* rowIdx = 0;
> *while* (rs.next()) {
> rowIdx++;
> *if* (rowIdx % 1000 == 0) {
> System.*out*.println("fetched " + rowIdx);
> }
> }
> }
>
> /**
>  * *@return* Random string 1000 chars
>  */
> *private* String getRandomString1K() {
> *char* [] buf = *new* *char*[1000];
> *for* (*int* idx = 0; idx < buf.len

Re: [h2] Query processing in H2 DB

2014-06-03 Thread Noel Grandin

http://h2database.com/html/architecture.html

On 2014-06-03 10:23 PM, krismat.des...@gmail.com wrote:

Yes, but where could I begin the analysis? The question is, how do the h2 
database processed a sql query? The individual
steps of the query processing, parsing and validating for example.



--
You received this message because you are subscribed to the Google Groups "H2 
Database" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to h2-database+unsubscr...@googlegroups.com.
To post to this group, send email to h2-database@googlegroups.com.
Visit this group at http://groups.google.com/group/h2-database.
For more options, visit https://groups.google.com/d/optout.


Re: [h2] Query processing in H2 DB

2014-06-03 Thread krismat . design
Yes, but where could I begin the analysis? The question is, how do the h2 
database processed a sql query? The individual steps of the query 
processing, parsing and validating for example.

Am Dienstag, 3. Juni 2014 13:24:13 UTC+2 schrieb Noel Grandin:
>
> It's in lots of files. You'll have to be more specific. 
>
> On 2014-06-03 12:55 PM, krismat...@gmail.com  wrote: 
> > 
> > I have a question about the H2 Database. Where can I analyzing the code 
> about query processing and optimization? 
> > In which data file is it? 
>

-- 
You received this message because you are subscribed to the Google Groups "H2 
Database" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to h2-database+unsubscr...@googlegroups.com.
To post to this group, send email to h2-database@googlegroups.com.
Visit this group at http://groups.google.com/group/h2-database.
For more options, visit https://groups.google.com/d/optout.


[h2] understanding preparestatement reuse

2014-06-03 Thread Adam McMahon
Hi,

I frequently use PreparedStatements, but I am a bit unsure how to properly 
"reuse" them.

I create a statement

String sql = "select * from users where score>?";
PreparedStatement ps = con.prepareStatement(sql);
ps.setInt(1, n);
ResultSet rs = ps.executeQuery();
// do stuff
rs.close();
ps.close();
con.close();

Now lets say that I want to later reuse that prepared statement, which is 
more accurate:

1) do I need to keep a reference to the actual PreparedStatment object (in 
this case "ps").  If this is the case, do I not close the prepared 
statement?
2) can I "reuse" the preapred statment by just sending the same sql String 
when creating a PresparedStatement from a connection. 

In other words, does the programmer need to keep around references of 
prepared statement objects, or does the database (in this case H2) keep a 
cache based on the parametrized sql String that is sent to the connection.  

Thanks for any help.
-Adam


-- 
You received this message because you are subscribed to the Google Groups "H2 
Database" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to h2-database+unsubscr...@googlegroups.com.
To post to this group, send email to h2-database@googlegroups.com.
Visit this group at http://groups.google.com/group/h2-database.
For more options, visit https://groups.google.com/d/optout.


[h2] web console Servlet - how to not allow others to create new databases

2014-06-03 Thread Adam McMahon
Hi,

We use embedded H2 in a webapp with tomcat. We use the servlet webconsole 
to manage the database.  Our database is password protected, which should 
allow some security.  But I don't see how to prevent an unauthorized user 
from creating a new database and filling it with junk if they visit the 
webconsole url.  Our current method to prevent this is to simply obscure 
the web-console url-pattern to something that is hard to guess or know - 
thus trying to prevent someone from stumbling upon it.   Though I do not 
think this is a full solid security method.

Any ideas or tips on how to 
1) secure the web-console servlet
2) prevent others from creating new databases if they find the url.

Thanks,
-Adam

-- 
You received this message because you are subscribed to the Google Groups "H2 
Database" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to h2-database+unsubscr...@googlegroups.com.
To post to this group, send email to h2-database@googlegroups.com.
Visit this group at http://groups.google.com/group/h2-database.
For more options, visit https://groups.google.com/d/optout.


[h2] Re: Recursive CTE don't work when recursion predicate uses a bind variable

2014-06-03 Thread Lukas Eder
In fact, there seems to be a second issue related to bind variables and 
recursive CTE. Consider the following alternative program:
>
>
Connection con = getConnection();
System.out.println("Wrong result:");
PreparedStatement stmt = con.prepareStatement(
"WITH recursive t(f) AS ( "+
"SELECT ? "+
"UNION ALL"+
"SELECT t.f + 1   "+
"FROM t   "+
"WHERE t.f < 10"+
")"+
"SELECT t.f   "+
"FROM t   "
);
stmt.setInt(1, 1);
ResultSet rs = stmt.executeQuery();

while (rs.next())
System.out.println(rs.getString(1));

System.out.println("Correct result:");
rs = con.createStatement().executeQuery(
"WITH recursive t(f) AS ( "+
"SELECT 1 "+
"UNION ALL"+
"SELECT t.f + 1   "+
"FROM t   "+
"WHERE t.f < 10   "+
")"+
"SELECT t.f   "+
"FROM t   "
);

while (rs.next())
System.out.println(rs.getString(1));

The output is now:

Wrong result:
*null*
Correct result:
1
2
3
4
5
6
7
8
9

-- 
You received this message because you are subscribed to the Google Groups "H2 
Database" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to h2-database+unsubscr...@googlegroups.com.
To post to this group, send email to h2-database@googlegroups.com.
Visit this group at http://groups.google.com/group/h2-database.
For more options, visit https://groups.google.com/d/optout.


[h2] Recursive CTE don't work when recursion predicate uses a bind variable

2014-06-03 Thread Lukas Eder
Java program to reproduce this:

Connection con = getConnection();
System.out.println("Wrong result:");
PreparedStatement stmt = con.prepareStatement(
"WITH recursive t(f) AS ( "+
"SELECT 1 "+
"UNION ALL"+
"SELECT t.f + 1   "+
"FROM t   "+
"WHERE t.f < ?"+
")"+
"SELECT t.f   "+
"FROM t   "
);
stmt.setInt(1, 10);
ResultSet rs = stmt.executeQuery();

while (rs.next())
System.out.println(rs.getInt(1));

System.out.println("Correct result:");
rs = con.createStatement().executeQuery(
"WITH recursive t(f) AS ( "+
"SELECT 1 "+
"UNION ALL"+
"SELECT t.f + 1   "+
"FROM t   "+
"WHERE t.f < 10   "+
")"+
"SELECT t.f   "+
"FROM t   "
);

while (rs.next())
System.out.println(rs.getInt(1));

The produced output is:


Wrong result:
1
Correct result:
1
2
3
4
5
6
7
8
9
10

-- 
You received this message because you are subscribed to the Google Groups "H2 
Database" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to h2-database+unsubscr...@googlegroups.com.
To post to this group, send email to h2-database@googlegroups.com.
Visit this group at http://groups.google.com/group/h2-database.
For more options, visit https://groups.google.com/d/optout.


[h2] State of the recursive CTE feature

2014-06-03 Thread Lukas Eder
Hello,

We're currently integrating support for CTE in jOOQ and we're wondering if
we should support CTE for H2 at all. H2 has experimental CTE support, if
I'm not mistaken:
http://www.h2database.com/html/advanced.html?highlight=recursive&search=recursive#recursive_queries

This would be one of our test cases, and it seems to work for H2:

with recursive "t1"("f1", "f2") as (
  select
1,
'a'
  from dual
union all
  select
("t1"."f1" + 1),
("t1"."f2" || 'a')
  from "t1"
  where "t1"."f1" < 10
)
select
  "t1"."f1",
  "t1"."f2"
from "t1"


However, in standard SQL, I can declare several tables in the WITH clause,
e.g.:

with recursive "t1"("f1", "f2") as (...),

   "t2"("g1", "g2") as (...),
   ...

select ...


This doesn't seem to work right now for H2.

Am I right in thinking that:

1. Only RECURSIVE CTE are currently supported, although I can tweak a
synthetic UNION ALL clause into the query to make H2 believe that we have
the required syntax (see below)
2. The RECURSIVE keyword seems to be optional - probably to be Oracle
compatible as in Oracle, recursiveness is implicit
3. Only single-table CTE are currently supported
4. This is currently still not a priority for the H2 maintenance team? (as
this question occasionally pops up on the user-group) :-)

[From 1] Non-recursive tweak to comply with H2 syntax requirements:

with "t1"("f1", "f2") as (
  select
1,
'a'
  from dual
union all
  select null, null
  where false
)
select
  "t1"."f1",
  "t1"."f2"
from "t1"


Any feedback is very welcome.

Cheers
Lukas

-- 
You received this message because you are subscribed to the Google Groups "H2 
Database" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to h2-database+unsubscr...@googlegroups.com.
To post to this group, send email to h2-database@googlegroups.com.
Visit this group at http://groups.google.com/group/h2-database.
For more options, visit https://groups.google.com/d/optout.


Re: [h2] Query processing in H2 DB

2014-06-03 Thread Noel Grandin

It's in lots of files. You'll have to be more specific.

On 2014-06-03 12:55 PM, krismat.des...@gmail.com wrote:


I have a question about the H2 Database. Where can I analyzing the code about 
query processing and optimization?
In which data file is it?


--
You received this message because you are subscribed to the Google Groups "H2 
Database" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to h2-database+unsubscr...@googlegroups.com.
To post to this group, send email to h2-database@googlegroups.com.
Visit this group at http://groups.google.com/group/h2-database.
For more options, visit https://groups.google.com/d/optout.


[h2] Re: Query processing in H2 DB

2014-06-03 Thread too
Hi,
I am not sure whether I understand the question but here are few tips to 
analyse H2 
performance http://zvikico.typepad.com/problog/2008/04/h2-performance.html

Tono

On Tuesday, June 3, 2014 12:55:58 PM UTC+2, krismat...@gmail.com wrote:
>
> Hello,
>
> I have a question about the H2 Database. Where can I analyzing the code 
> about query processing and optimization?
> In which data file is it?
>
> Thanks for each help :-)
>

-- 
You received this message because you are subscribed to the Google Groups "H2 
Database" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to h2-database+unsubscr...@googlegroups.com.
To post to this group, send email to h2-database@googlegroups.com.
Visit this group at http://groups.google.com/group/h2-database.
For more options, visit https://groups.google.com/d/optout.


[h2] Query processing in H2 DB

2014-06-03 Thread krismat . design
Hello,

I have a question about the H2 Database. Where can I analyzing the code 
about query processing and optimization?
In which data file is it?

Thanks for each help :-)

-- 
You received this message because you are subscribed to the Google Groups "H2 
Database" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to h2-database+unsubscr...@googlegroups.com.
To post to this group, send email to h2-database@googlegroups.com.
Visit this group at http://groups.google.com/group/h2-database.
For more options, visit https://groups.google.com/d/optout.


[h2] ARRAY_AGG() support

2014-06-03 Thread Lukas Eder
Hello,

I just wanted to create an example for a blog post and noticed that there
is (probably?) no way to aggregate data into an array, the way PostgreSQL
allows it through ARRAY_AGG():
http://www.postgresql.org/docs/9.3/interactive/functions-aggregate.html

An example in PostgreSQL:

select

  t.table_schema,

  t.table_name,
  array_agg(c.column_name::varchar order by c.ordinal_position)
from information_schema.tables t
join information_schema.columns c
on (t.table_schema, t.table_name)
 = (c.table_schema, c.table_name)
group by t.table_schema, t.table_name

Sample output:

"information_schema";"enabled_roles";"{role_name}"
"information_schema";"foreign_data_wrapper_options";"{foreign_data_wrapper_catalog,foreign_data_wrapper_name,option_name,option_value}"
"information_schema";"foreign_data_wrappers";"{foreign_data_wrapper_catalog,foreign_data_wrapper_name,authorization_identifier,library_name,foreign_data_wrapper_language}"
"information_schema";"foreign_server_options";"{foreign_server_catalog,foreign_server_name,option_name,option_value}"


Do you think this would be a useful addition to the roadmap?

Cheers
Lukas

-- 
You received this message because you are subscribed to the Google Groups "H2 
Database" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to h2-database+unsubscr...@googlegroups.com.
To post to this group, send email to h2-database@googlegroups.com.
Visit this group at http://groups.google.com/group/h2-database.
For more options, visit https://groups.google.com/d/optout.


Re: [h2] Exception when opening DB after forced shutdown (1.3.176)

2014-06-03 Thread too
Hello,
I can test the fix for you easily, all I need is h2 jar with fix. 

Regarding the test I tried all I could think of. Our app is fairly large 
(15MB jar of classes with lots of framework-ish stuff happening in the 
background) so it is difficult to point out the scenario. Tried INFO 
logging to re-execute the same set of queries but that has not replicated 
the problem. I am also pretty sure we do not create any temporary tables 
explicitly (also searched code-base for "create memory table").

Can you point me in some direction as what to look for? I mean what would 
you expect to be happening to create the table? Does H2 create temp tables 
implicitly? All we do to trigger the problem are select queries (based on 
the info log I had).

thanks
Tono

On Monday, June 2, 2014 6:04:03 PM UTC+2, Thomas Mueller wrote:
>
> Hi,
>
> I could analyze it now. The problem seems to be that creating a temporary 
> table is not committed, and then the temporary table is deleted in another 
> session. I have a fix / workaround for that, but so far no test case. 
> Please tell me if you have a reproducible test case.
>
> Regards,
> Thomas
>
>
>
> On Tuesday, May 27, 2014, too > wrote:
>
>> Even though I can reproduce this with our app I fail to create separate 
>> test case to reproduce the problem (i.e. to break the DB). What I can do is 
>> send you database that H2 fails to open. Perhaps it is not really bug 
>> during close but not robust enough recovery during startup. Zipped DB has 
>> 10MB and I can share it for you privately if you think that can help
>>
>> thanks
>> Tono
>>
>> On Thursday, May 22, 2014 5:47:11 PM UTC+2, too wrote:
>>
>> I have experimented with this a little and here are few notes
>>
>>- lock file remains in place - this is consistent with shutdown hooks 
>>not being executed during JVM abort
>>- size of DB file remains intact during runtime but during process 
>>termination the size rises by approximately 50MB - which contradicts 
>>previous point and it seems there is something executed during abort 
>>- I can replicate problem with 100% success rate using our app but I 
>>fail to create test app to replicate the problem (still have a few ideas 
>> to 
>>try)
>>- I can replicate the problem with older 1.3.x releases as well as 
>>with latest 1.4.x release (with MV_STORE=FALSE) 
>>- even though I do not think that there are transactions in progress 
>>at the time of termination it is possible there are open cursors or 
>>something similar - read-related
>>
>> I can avoid this problem by running H2 in server mode but that is not 
>> what I want. 
>>
>> Tono
>>
>> On Tuesday, May 20, 2014 3:16:03 PM UTC+2, too wrote:
>>
>> Hi,
>> Sometimes when our application is shut down forcibly it is unable to 
>> start again with exceptions below. It does not appear that transaction is 
>> in progress at the time of shutdown but I can not be sure. I was unable to 
>> create test case but our application reproduces this quite consistently 
>> (it's very rare that it starts after being terminated). 
>> I have attached debug trace file for failed start - not for the shutdown. 
>> I tried INFO logging for shutdown (breaking the db) but nothing seemed 
>> interesting there, just bunch of selects. Also no error is logged during 
>> shutdown or startup.
>>
>> Environment details are
>>
>>- H2 - 1.3.176
>>- Java Runtime - Java(TM) SE Runtime Environment (1.7.0_17-b02, 
>>32b) on Java HotSpot(TM) Client VM (23.7-b01, mixed mode)
>>- Operating System - Windows 7 (64b, Service Pack 1, version 6.1) 
>>- connection URL - jdbc:h2:./dbfile;IFEXISTS=TRUE
>>
>>
>> NullPointerException - this is what usually happens
>>
>> org.h2.jdbc.JdbcSQLException: General error: 
>> "java.lang.NullPointerException" 
>> [5-176]
>>  at org.h2.message.DbException.getJdbcSQLException(DbException.java:344) 
>> ~[h2.jar:1.3.176]
>>  at org.h2.message.DbException.get(DbException.java:167) 
>> ~[h2.jar:1.3.176]
>> at org.h2.message.DbException.convert(DbException.java:294) 
>> ~[h2.jar:1.3.176]
>>  at org.h2.engine.Database.openDatabase(Database.java:291) 
>> ~[h2.jar:1.3.176]
>> at org.h2.engine.Database.(Database.java:254) ~[h2.jar:1.3.176]
>>  at org.h2.engine.Engine.openSession(Engine.java:57) ~[h2.jar:1.3.176]
>> at org.h2.engine.Engine.openSession(Engine.java:164) ~[h2.jar:1.3.176]
>>  at org.h2.engine.Engine.createSessionAndValidate(Engine.java:142) 
>> ~[h2.jar:1.3.176]
>>  at org.h2.engine.Engine.createSession(Engine.java:125) ~[h2.jar:1.3.176]
>> at org.h2.engine.Engine.createSession(Engine.java:27) ~[h2.jar:1.3.176]
>>
>>  -- 
>> You received this message because you are subscribed to the Google Groups 
>> "H2 Database" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to h2-database+unsubscr...@googlegroups.com.
>> To post to this group, send email to h2-database@googlegroups.com.
>> Visit this group at http:/

Re: [h2] Corruption in a database created in 1.3.174 when opening and closing it in 1.3.176

2014-06-03 Thread Cecil Westerhof
2014-06-02 18:04 GMT+02:00 Thomas Mueller :

> Yes, this problem was introduced in version 1.3.176, actually by fixing
> another bug. It happens when upgrading a database with a special kind of
> foreign key constraint from an older version to 1.3.176. I found the
> problem now and have a fix for it. I will need to release a new version; a
> workaround is to stay with the older version, or upgrade to the newer
> version by first converting to a SQL script and then creating a new
> database.
>

​Just to be sure. In the new version the problem is solved and I do not
need to convert the db?

I do not think there are important changes (for me) in 176, so I just wait
until the new version is deployed.

-- 
Cecil Westerhof

-- 
You received this message because you are subscribed to the Google Groups "H2 
Database" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to h2-database+unsubscr...@googlegroups.com.
To post to this group, send email to h2-database@googlegroups.com.
Visit this group at http://groups.google.com/group/h2-database.
For more options, visit https://groups.google.com/d/optout.