1616 * specific language governing permissions and limitations
1717 * under the License.
1818 */
19- \! cp -r regress/age_load/data regress/instance/data/age_load
2019LOAD 'age';
2120SET search_path TO ag_catalog;
2221SET enable_mergejoin = ON;
@@ -385,6 +384,19 @@ CREATE INDEX load_city_gin_idx
385384ON cypher_index."City" USING gin (properties);
386385CREATE INDEX load_country_gin_idx
387386ON cypher_index."Country" USING gin (properties);
387+ -- Verify GIN index is used for City property match
388+ SELECT * FROM cypher('cypher_index', $$
389+ EXPLAIN (costs off) MATCH (c:City {city_id: 1})
390+ RETURN c
391+ $$) as (plan agtype);
392+ QUERY PLAN
393+ --------------------------------------------------------------
394+ Bitmap Heap Scan on "City" c
395+ Recheck Cond: (properties @> '{"city_id": 1}'::agtype)
396+ -> Bitmap Index Scan on load_city_gin_idx
397+ Index Cond: (properties @> '{"city_id": 1}'::agtype)
398+ (4 rows)
399+
388400SELECT * FROM cypher('cypher_index', $$
389401 MATCH (c:City {city_id: 1})
390402 RETURN c
@@ -418,6 +430,19 @@ $$) as (n agtype);
418430 {"id": 1970324836974597, "label": "City", "properties": {"name": "Vancouver", "city_id": 5, "west_coast": true, "country_code": "CA"}}::vertex
419431(4 rows)
420432
433+ -- Verify GIN index is used for Country property match
434+ SELECT * FROM cypher('cypher_index', $$
435+ EXPLAIN (costs off) MATCH (c:Country {life_expectancy: 82.05})
436+ RETURN c
437+ $$) as (plan agtype);
438+ QUERY PLAN
439+ --------------------------------------------------------------------------
440+ Bitmap Heap Scan on "Country" c
441+ Recheck Cond: (properties @> '{"life_expectancy": 82.05}'::agtype)
442+ -> Bitmap Index Scan on load_country_gin_idx
443+ Index Cond: (properties @> '{"life_expectancy": 82.05}'::agtype)
444+ (4 rows)
445+
421446SELECT * FROM cypher('cypher_index', $$
422447 MATCH (c:Country {life_expectancy: 82.05})
423448 RETURN c
@@ -441,26 +466,259 @@ DROP INDEX cypher_index.load_country_gin_idx;
441466--
442467-- Section 4: Index use with WHERE clause
443468--
444- SELECT COUNT(*) FROM cypher('cypher_index', $$
469+ -- Create expression index on country_code property
470+ CREATE INDEX city_country_code_idx ON cypher_index."City"
471+ (ag_catalog.agtype_access_operator(properties, '"country_code"'::agtype));
472+ -- Verify index is used with EXPLAIN (should show Index Scan on city_country_code_idx)
473+ SELECT * FROM cypher('cypher_index', $$
474+ EXPLAIN (costs off) MATCH (a:City)
475+ WHERE a.country_code = 'US'
476+ RETURN a
477+ $$) as (plan agtype);
478+ QUERY PLAN
479+ ---------------------------------------------------------------------------------------------------------------
480+ Index Scan using city_country_code_idx on "City" a
481+ Index Cond: (agtype_access_operator(VARIADIC ARRAY[properties, '"country_code"'::agtype]) = '"US"'::agtype)
482+ (2 rows)
483+
484+ -- Test WHERE with indexed string property
485+ SELECT * FROM cypher('cypher_index', $$
445486 MATCH (a:City)
446- WHERE a.country_code = 'RS'
487+ WHERE a.country_code = 'US'
488+ RETURN a.name
489+ ORDER BY a.city_id
490+ $$) as (name agtype);
491+ name
492+ -----------------
493+ "New York"
494+ "San Fransisco"
495+ "Los Angeles"
496+ "Seattle"
497+ (4 rows)
498+
499+ SELECT * FROM cypher('cypher_index', $$
500+ MATCH (a:City)
501+ WHERE a.country_code = 'CA'
502+ RETURN a.name
503+ ORDER BY a.city_id
504+ $$) as (name agtype);
505+ name
506+ -------------
507+ "Vancouver"
508+ "Toronto"
509+ "Montreal"
510+ (3 rows)
511+
512+ -- Test WHERE with no matching results
513+ SELECT * FROM cypher('cypher_index', $$
514+ MATCH (a:City)
515+ WHERE a.country_code = 'XX'
516+ RETURN a.name
517+ $$) as (name agtype);
518+ name
519+ ------
520+ (0 rows)
521+
522+ -- Create expression index on city_id property
523+ CREATE INDEX city_id_idx ON cypher_index."City"
524+ (ag_catalog.agtype_access_operator(properties, '"city_id"'::agtype));
525+ -- Verify index is used with EXPLAIN for integer property
526+ SELECT * FROM cypher('cypher_index', $$
527+ EXPLAIN (costs off) MATCH (a:City)
528+ WHERE a.city_id = 1
447529 RETURN a
448- $$) as (n agtype);
449- count
450- -------
451- 0
530+ $$) as (plan agtype);
531+ QUERY PLAN
532+ -------------------------------------------------------------------------------------------------------
533+ Index Scan using city_id_idx on "City" a
534+ Index Cond: (agtype_access_operator(VARIADIC ARRAY[properties, '"city_id"'::agtype]) = '1'::agtype)
535+ (2 rows)
536+
537+ -- Test WHERE with indexed integer property
538+ SELECT * FROM cypher('cypher_index', $$
539+ MATCH (a:City)
540+ WHERE a.city_id = 1
541+ RETURN a.name
542+ $$) as (name agtype);
543+ name
544+ ------------
545+ "New York"
452546(1 row)
453547
454- CREATE INDEX CONCURRENTLY cntry_ode_idx ON cypher_index."City"
455- (ag_catalog.agtype_access_operator(properties, '"country_code"'::agtype));
456- SELECT COUNT(*) FROM cypher('agload_test_graph', $$
548+ SELECT * FROM cypher('cypher_index', $$
457549 MATCH (a:City)
458- WHERE a.country_code = 'RS'
550+ WHERE a.city_id = 5
551+ RETURN a.name
552+ $$) as (name agtype);
553+ name
554+ -------------
555+ "Vancouver"
556+ (1 row)
557+
558+ -- Test WHERE with comparison operators on indexed property
559+ SELECT * FROM cypher('cypher_index', $$
560+ MATCH (a:City)
561+ WHERE a.city_id < 3
562+ RETURN a.name
563+ ORDER BY a.city_id
564+ $$) as (name agtype);
565+ name
566+ -----------------
567+ "New York"
568+ "San Fransisco"
569+ (2 rows)
570+
571+ SELECT * FROM cypher('cypher_index', $$
572+ MATCH (a:City)
573+ WHERE a.city_id >= 8
574+ RETURN a.name
575+ ORDER BY a.city_id
576+ $$) as (name agtype);
577+ name
578+ -------------
579+ "Monterrey"
580+ "Tijuana"
581+ (2 rows)
582+
583+ -- Create expression index on west_coast boolean property
584+ CREATE INDEX city_west_coast_idx ON cypher_index."City"
585+ (ag_catalog.agtype_access_operator(properties, '"west_coast"'::agtype));
586+ -- Verify index is used with EXPLAIN for boolean property
587+ SELECT * FROM cypher('cypher_index', $$
588+ EXPLAIN (costs off) MATCH (a:City)
589+ WHERE a.west_coast = true
459590 RETURN a
460- $$) as (n agtype);
461- ERROR: graph "agload_test_graph" does not exist
462- LINE 1: SELECT COUNT(*) FROM cypher('agload_test_graph', $$
463- ^
591+ $$) as (plan agtype);
592+ QUERY PLAN
593+ -------------------------------------------------------------------------------------------------------------
594+ Index Scan using city_west_coast_idx on "City" a
595+ Index Cond: (agtype_access_operator(VARIADIC ARRAY[properties, '"west_coast"'::agtype]) = 'true'::agtype)
596+ (2 rows)
597+
598+ -- Test WHERE with indexed boolean property
599+ SELECT * FROM cypher('cypher_index', $$
600+ MATCH (a:City)
601+ WHERE a.west_coast = true
602+ RETURN a.name
603+ ORDER BY a.city_id
604+ $$) as (name agtype);
605+ name
606+ -----------------
607+ "San Fransisco"
608+ "Los Angeles"
609+ "Seattle"
610+ "Vancouver"
611+ (4 rows)
612+
613+ SELECT * FROM cypher('cypher_index', $$
614+ MATCH (a:City)
615+ WHERE a.west_coast = false
616+ RETURN a.name
617+ ORDER BY a.city_id
618+ $$) as (name agtype);
619+ name
620+ ---------------
621+ "New York"
622+ "Toronto"
623+ "Montreal"
624+ "Mexico City"
625+ "Monterrey"
626+ "Tijuana"
627+ (6 rows)
628+
629+ -- Test WHERE with multiple conditions (AND)
630+ SELECT * FROM cypher('cypher_index', $$
631+ MATCH (a:City)
632+ WHERE a.country_code = 'US' AND a.west_coast = true
633+ RETURN a.name
634+ ORDER BY a.city_id
635+ $$) as (name agtype);
636+ name
637+ -----------------
638+ "San Fransisco"
639+ "Los Angeles"
640+ "Seattle"
641+ (3 rows)
642+
643+ -- Test WHERE with OR conditions
644+ SELECT * FROM cypher('cypher_index', $$
645+ MATCH (a:City)
646+ WHERE a.city_id = 1 OR a.city_id = 5
647+ RETURN a.name
648+ ORDER BY a.city_id
649+ $$) as (name agtype);
650+ name
651+ -------------
652+ "New York"
653+ "Vancouver"
654+ (2 rows)
655+
656+ -- Test WHERE with NOT
657+ SELECT * FROM cypher('cypher_index', $$
658+ MATCH (a:City)
659+ WHERE NOT a.west_coast = true AND a.country_code = 'US'
660+ RETURN a.name
661+ $$) as (name agtype);
662+ name
663+ ------------
664+ "New York"
665+ (1 row)
666+
667+ -- Create expression index on life_expectancy for Country
668+ CREATE INDEX country_life_exp_idx ON cypher_index."Country"
669+ (ag_catalog.agtype_access_operator(properties, '"life_expectancy"'::agtype));
670+ -- Verify index is used with EXPLAIN for float property
671+ SELECT * FROM cypher('cypher_index', $$
672+ EXPLAIN (costs off) MATCH (c:Country)
673+ WHERE c.life_expectancy > 80.0
674+ RETURN c
675+ $$) as (plan agtype);
676+ QUERY PLAN
677+ ------------------------------------------------------------------------------------------------------------------
678+ Index Scan using country_life_exp_idx on "Country" c
679+ Index Cond: (agtype_access_operator(VARIADIC ARRAY[properties, '"life_expectancy"'::agtype]) > '80.0'::agtype)
680+ (2 rows)
681+
682+ -- Test WHERE with float property
683+ SELECT * FROM cypher('cypher_index', $$
684+ MATCH (c:Country)
685+ WHERE c.life_expectancy > 80.0
686+ RETURN c.name
687+ $$) as (name agtype);
688+ name
689+ ----------
690+ "Canada"
691+ (1 row)
692+
693+ SELECT * FROM cypher('cypher_index', $$
694+ MATCH (c:Country)
695+ WHERE c.life_expectancy < 76.0
696+ RETURN c.name
697+ $$) as (name agtype);
698+ name
699+ ----------
700+ "Mexico"
701+ (1 row)
702+
703+ -- Test WHERE in combination with pattern matching
704+ SELECT * FROM cypher('cypher_index', $$
705+ MATCH (country:Country)<-[:has_city]-(city:City)
706+ WHERE country.country_code = 'CA'
707+ RETURN city.name
708+ ORDER BY city.city_id
709+ $$) as (name agtype);
710+ name
711+ -------------
712+ "Vancouver"
713+ "Toronto"
714+ "Montreal"
715+ (3 rows)
716+
717+ -- Clean up indices
718+ DROP INDEX cypher_index.city_country_code_idx;
719+ DROP INDEX cypher_index.city_id_idx;
720+ DROP INDEX cypher_index.city_west_coast_idx;
721+ DROP INDEX cypher_index.country_life_exp_idx;
464722--
465723-- General Cleanup
466724--
@@ -478,5 +736,3 @@ NOTICE: graph "cypher_index" has been dropped
478736
479737(1 row)
480738
481- SELECT drop_graph('agload_test_graph', true);
482- ERROR: graph "agload_test_graph" does not exist
0 commit comments