Permalink
Browse files

Accessors C module fixes

  • Loading branch information...
1 parent 18d523b commit 1d4f3e274a6ac84f6874399ccb1912e0f635d0ba @theirix committed Sep 27, 2012
Showing with 12 additions and 235 deletions.
  1. +2 −1 Makefile
  2. +10 −21 json_accessors.c
  3. +0 −95 sql/postgre-json-gin.sql
  4. +0 −118 test-gin-performance.sql
View
@@ -4,7 +4,8 @@ OBJS = json_accessors.o cJSON.o
EXTENSION = json_accessors_c
DATA = json_accessors_c--1.2.sql
-PG_CPPFLAGS = -g -O0
+PG_CPPFLAGS =
+REGRESS = postgre-json-functions
PG_CONFIG := pg_config
PGXS := $(shell $(PG_CONFIG) --pgxs)
View
@@ -12,24 +12,13 @@
*-------------------------------------------------------------------------
*/
-// todo[alexey]: remove GIN headers
#include "postgres.h"
-#include "fmgr.h"
-#include "catalog/pg_collation.h"
-#include "catalog/pg_proc.h"
#include "catalog/pg_type.h"
-#include "access/gin.h"
-#include "access/skey.h"
-#include "access/tuptoaster.h"
-#include "utils/fmgroids.h"
#include "utils/builtins.h"
-#include "utils/numeric.h"
-#include "utils/int8.h"
#include "utils/timestamp.h"
#include "utils/array.h"
#include "utils/lsyscache.h"
#include "utils/formatting.h"
-#include "utils/fmgroids.h"
/*
* Note. cJSON should be patched for this extension.
@@ -298,16 +287,16 @@ Datum json_array_to_array_generic_impl(cJSON *jsonArray, int json_type, Oid elem
for (elem = jsonArray->child; elem; elem = elem->next)
{
-// todo [alexey]: check this change
-// if (elem->child)
-// ereport(ERROR,
-// (errcode(ERRCODE_WRONG_OBJECT_TYPE),
-// errmsg("no childs allowed")));
-// if (!(json_type == CJSON_TYPE_ANY || match_json_types(json_type, elem->type)))
-// ereport(ERROR,
-// (errcode(ERRCODE_WRONG_OBJECT_TYPE),
-// errmsg("expected value of type %s, actual %s at %d position",
-// json_type_str(json_type), json_type_str(elem->type), ind)));
+ /*todo [alexey]: check this change*/
+ if (elem->child)
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("no childs allowed")));
+ if (!(json_type == CJSON_TYPE_ANY || match_json_types(json_type, elem->type)))
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("expected value of type %s, actual %s at %d position",
+ json_type_str(json_type), json_type_str(elem->type), ind)));
++count;
}
View
@@ -1,95 +0,0 @@
-set client_min_messages to 'error';
-drop extension if exists "postgre-json-functions" cascade;
-create extension "postgre-json-functions";
-set client_min_messages to 'notice';
-
-\t on
-\pset format unaligned
-
--- t
-select array['foo', 'bar', 'baz'] @> array['foo'];
--- t
-select array['foo', 'bar', 'baz'] @> array['foo', 'bar'];
--- t
-select array['foo', 'bar', 'baz'] @> array['baz', 'foo'];
--- f
-select array['foo', 'bar', 'baz'] @> array['qux'];
--- t
-select array['foo', 'bar', 'baz'] @> array[]::text[];
--- t
-select array[]::text[] @> array[]::text[];
--- f
-select array[]::text[] @> array['qux'];
-
--- t
-select array['foo', 'bar', 'baz'] @@> array['foo'];
--- t
-select array['foo', 'bar', 'baz'] @@> array['foo', 'bar'];
--- t
-select array['foo', 'bar', 'baz'] @@> array['baz', 'foo'];
--- f
-select array['foo', 'bar', 'baz'] @@> array['qux'];
--- t
-select array['foo', 'bar', 'baz'] @@> array[]::text[];
--- t
-select array[]::text[] @> array[]::text[];
--- f
-select array[]::text[] @> array['qux'];
-
--- t
-select array['foo', 'bar', 'baz'] @@> array['fo'];
--- t
-select array['foo', 'bar', 'baz'] @@> array['ba'];
--- t
-select array['foo', 'bar', 'baz'] @@> array['b'];
--- t
-select array['foo', 'bar', 'baz'] @@> array[''];
--- f
-select array['foo', 'bar', 'baz'] @@> array['baq'];
--- t
-select array['foo', 'foobar', 'baz'] @@> array['foo'];
-
-set client_min_messages to 'error';
-drop table if exists test_table;
-create table test_table(id bigserial, val text);
-set client_min_messages to 'notice';
-
-insert into test_table(val) values('{"create_date":"2009-12-01 01:23:45","tags":["foo1","bar1","baz1"]}');
-insert into test_table(val) values('{"create_date":"2009-12-02 01:23:45","tags":["foo2","bar2","baz2"]}');
-insert into test_table(val) values('{"create_date":"2009-12-03 01:23:45","tags":["foo3","bar3","baz3"]}');
-insert into test_table(val) select val from test_table;
-insert into test_table(val) select val from test_table;
-insert into test_table(val) select val from test_table;
-insert into test_table(val) values('{"create_date":"2009-12-04 01:23:45","tags":["foo4","bar4","baz4"]}');
-insert into test_table(val) values('{"create_date":"2009-12-04 01:23:45","tags":["foo4","bar4","baz4"]}');
-insert into test_table(val) values('{"create_date":"2009-12-04 01:23:45","tags":["foo4","bar4","baz4"]}');
-insert into test_table(val) values('{"create_date":"2009-12-04 01:23:45","tags":["foo4","bar4one","baz4"]}');
-insert into test_table(val) values('{"create_date":"2009-12-04 01:23:45","tags":["foo4","bar4two","baz4"]}');
-insert into test_table(val) values('{"create_date":"2009-12-04 01:23:45","tags":["foo4","bar4three","baz4"]}');
-
--- 30
-select count(*) from test_table;
-
--- NOTICE: index "test_tags_idx" does not exist, skipping
-drop index if exists test_tags_idx;
-create index test_tags_idx on test_table using gin (json_object_get_text_array(val, 'tags') json_gin_ops);
-
--- 6
-select count(*) from test_table where json_object_get_text_array(val, 'tags') @@> array['bar4'];
--- 3
-select count(*) from test_table where json_object_get_text_array(val, 'tags') @> array['bar4'];
--- 8
-select count(*) from test_table where json_object_get_text_array(val, 'tags') @@> array['bar3'];
--- 8
-select count(*) from test_table where json_object_get_text_array(val, 'tags') @> array['bar3'];
--- 0
-select count(*) from test_table where json_object_get_text_array(val, 'tags') @@> array['qux'];
--- 0
-select count(*) from test_table where json_object_get_text_array(val, 'tags') @> array['qux'];
------ select count(*) from test_table where json_object_get_text_array(val, 'tags') @@> array[]::text[];
------ select count(*) from test_table where json_object_get_text_array(val, 'tags') @> array[]::text[];
--- 30
-select count(*) from test_table where json_object_get_text_array(val, 'tags') @@> array[''];
-
-\t off
-\pset format aligned
View
@@ -1,118 +0,0 @@
-drop extension "postgre-json-functions" cascade;
-create extension "postgre-json-functions";
-
--- create table
-drop table if exists test_table;
-create table test_table(id bigserial, val text);
-
--- insert data (1572867 rows)
-insert into test_table(val) values('{"create_date":"2009-12-01 01:23:45","tags":["foo1","bar1","baz1"]}');
-insert into test_table(val) values('{"create_date":"2009-12-02 01:23:45","tags":["foo2","bar2","baz2"]}');
-insert into test_table(val) values('{"create_date":"2009-12-03 01:23:45","tags":["foo3","bar3","baz3"]}');
-insert into test_table(val) select val from test_table;
-insert into test_table(val) select val from test_table;
-insert into test_table(val) select val from test_table;
-insert into test_table(val) select val from test_table;
---insert into test_table(val) select val from test_table;
---insert into test_table(val) select val from test_table;
---insert into test_table(val) select val from test_table;
---insert into test_table(val) select val from test_table;
---insert into test_table(val) select val from test_table;
---insert into test_table(val) select val from test_table;
---insert into test_table(val) select val from test_table;
---insert into test_table(val) select val from test_table;
---insert into test_table(val) select val from test_table;
-insert into test_table(val) values('{"create_date":"2009-12-04 01:23:45","tags":["foo4","bar4","baz4"]}');
-insert into test_table(val) values('{"create_date":"2009-12-04 01:23:45","tags":["foo4","bar4","baz4"]}');
-insert into test_table(val) values('{"create_date":"2009-12-04 01:23:45","tags":["foo4","bar4","baz4"]}');
-
-insert into test_table(val) values('{"create_date":"2009-12-04 01:23:45","tags":["foo4","bar4one","baz4"]}');
-insert into test_table(val) values('{"create_date":"2009-12-04 01:23:45","tags":["foo4","bar4two","baz4"]}');
-insert into test_table(val) values('{"create_date":"2009-12-04 01:23:45","tags":["foo4","bar4three","baz4"]}');
-
-
-select count(*) from test_table;
-
--- JSON object fields query
-
--- slow query
---select * from test_table where json_object_get_timestamp(val, 'create_date') between '2009-12-04 01:00:00' and '2009-12-04 02:00:00';
--- Seq Scan on test_table (cost=0.00..830998.51 rows=7864 width=76) (actual time=21904.068..21904.124 rows=3 loops=1)
--- Filter: ((json_object_get_timestamp(val, 'create_date'::text) >= '2009-12-04 01:00:00'::timestamp without time zone) AND (json_object_get_timestamp(val, 'create_date'::text) <= '2009-12-04 02:00:00'::timestamp without time zone))
--- Total runtime: 21904.157 ms
-
--- create btree index
---drop index if exists test_date_idx;
---create index test_date_idx on test_table using btree (json_object_get_timestamp(val, 'create_date'));
-
--- fast query
---select * from test_table where json_object_get_timestamp(val, 'create_date') between '2009-12-04 01:00:00' and '2009-12-04 02:00:00';
--- Bitmap Heap Scan on test_table (cost=169.53..19545.85 rows=7864 width=76) (actual time=0.023..0.026 rows=3 loops=1)
--- Recheck Cond: ((json_object_get_timestamp(val, 'create_date'::text) >= '2009-12-04 01:00:00'::timestamp without time zone) AND (json_object_get_timestamp(val, 'create_date'::text) <= '2009-12-04 02:00:00'::timestamp without time zone))
--- -> Bitmap Index Scan on test_date_idx (cost=0.00..167.56 rows=7864 width=0) (actual time=0.015..0.015 rows=3 loops=1)
--- Index Cond: ((json_object_get_timestamp(val, 'create_date'::text) >= '2009-12-04 01:00:00'::timestamp without time zone) AND (json_object_get_timestamp(val, 'create_date'::text) <= '2009-12-04 02:00:00'::timestamp without time zone))
--- Total runtime: 0.057 ms
-
--- JSON array inclusion query
-
--- slow query
---explain analyze select * from test_table where json_object_get_text_array(val, 'tags') @> array['bar4'];
--- Seq Scan on test_table (cost=0.00..827066.34 rows=1573 width=76) (actual time=41336.691..41336.749 rows=3 loops=1)
--- Filter: (json_array_to_text_array(json_object_get_text(val, 'tags'::text)) @> '{bar4}'::text[])
--- Total runtime: 41336.799 ms
-
--- create gin index, Mk I
--- http://www.postgresql.org/docs/9.0/static/gin.html
---drop index if exists test_tags_idx;
---create index test_tags_idx on test_table using gin (json_object_get_text_array(val, 'tags'));
-
--- fast query
---explain analyze select * from test_table where json_object_get_text_array(val, 'tags') @> array['bar4'];
--- Bitmap Heap Scan on test_table (cost=29.08..5679.25 rows=1573 width=76) (actual time=0.050..0.055 rows=3 loops=1)
--- Recheck Cond: (json_array_to_text_array(json_object_get_text(val, 'tags'::text)) @> '{bar4}'::text[])
--- -> Bitmap Index Scan on test_tags_idx (cost=0.00..28.69 rows=1573 width=0) (actual time=0.037..0.037 rows=3 loops=1)
--- Index Cond: (json_array_to_text_array(json_object_get_text(val, 'tags'::text)) @> '{bar4}'::text[])
--- Total runtime: 0.129 ms
-
--- create gin index, Mk II
-drop index if exists test_tags_idx;
-create index test_tags_idx on test_table using gin (json_object_get_text_array(val, 'tags') json_gin_ops);
-
--- fast query
--- explain analyze select * from test_table where json_object_get_text_array(val, 'tags') @> array['bar4'];
--- expects 3 rows
-
-\echo "Initial"
-explain analyze select * from test_table where json_object_get_text_array(val, 'tags') @@> array['bar4'];
-select count(*) from test_table where json_object_get_text_array(val, 'tags') @@> array['bar4'];
-
-\echo "Select using seq scan"
-set enable_indexscan=0;
-set enable_seqscan=1;
-explain analyze select * from test_table where json_object_get_text_array(val, 'tags') @@> array['bar4'];
-select count(*) from test_table where json_object_get_text_array(val, 'tags') @@> array['bar4'];
-
-\echo "Select using index (GIN) scan"
-set enable_indexscan=1;
-set enable_seqscan=0;
-explain analyze select * from test_table where json_object_get_text_array(val, 'tags') @@> array['bar4'];
-select count(*) from test_table where json_object_get_text_array(val, 'tags') @@> array['bar4'];
-
-\echo "Let Postgres choose the winner"
-\echo " but usually it fails..."
-set enable_indexscan=1;
-set enable_seqscan=1;
-explain analyze select * from test_table where json_object_get_text_array(val, 'tags') @@> array['bar4'];
-select count(*) from test_table where json_object_get_text_array(val, 'tags') @@> array['bar4'];
-
-\echo "Some integrity checks"
-select count(*), 6 as expected from test_table where json_object_get_text_array(val, 'tags') @@> array['bar4'];
-select count(*), 3 as expected from test_table where json_object_get_text_array(val, 'tags') @> array['bar4'];
-select count(*), 8192 as expected from test_table where json_object_get_text_array(val, 'tags') @@> array['bar3'];
-select count(*), 8192 as expected from test_table where json_object_get_text_array(val, 'tags') @> array['bar3'];
-select count(*), 0 as expected from test_table where json_object_get_text_array(val, 'tags') @@> array['qux'];
-select count(*), 0 as expected from test_table where json_object_get_text_array(val, 'tags') @> array['qux'];
-select count(*), 'anything' as expected from test_table where json_object_get_text_array(val, 'tags') @@> array[]::text[];
-select count(*), 'anything' as expected from test_table where json_object_get_text_array(val, 'tags') @> array[]::text[];
-select count(*), 24582 as expected from test_table where json_object_get_text_array(val, 'tags') @@> array[''];
-

0 comments on commit 1d4f3e2

Please sign in to comment.