@@ -698,3 +698,113 @@ TEST_F(ExprEvalTest, ArrayConstructorReturnsNull) {
698698 AstNode* n = make_node (arena, NodeType::NODE_ARRAY_CONSTRUCTOR);
699699 EXPECT_TRUE (eval_mysql (n).is_null ());
700700}
701+
702+ // ===== Array Subscript Evaluation =====
703+
704+ TEST_F (ExprEvalTest, ArraySubscriptPg1Based) {
705+ // ARRAY[10, 20, 30][2] with PostgreSQL -> 20 (1-based)
706+ AstNode* arr = make_node (arena, NodeType::NODE_ARRAY_CONSTRUCTOR);
707+ arr->add_child (leaf (NodeType::NODE_LITERAL_INT, " 10" ));
708+ arr->add_child (leaf (NodeType::NODE_LITERAL_INT, " 20" ));
709+ arr->add_child (leaf (NodeType::NODE_LITERAL_INT, " 30" ));
710+
711+ AstNode* subscript = make_node (arena, NodeType::NODE_ARRAY_SUBSCRIPT);
712+ subscript->add_child (arr);
713+ subscript->add_child (leaf (NodeType::NODE_LITERAL_INT, " 2" ));
714+
715+ auto v = eval_pg (subscript);
716+ EXPECT_EQ (v.tag , Value::TAG_INT64);
717+ EXPECT_EQ (v.int_val , 20 );
718+ }
719+
720+ TEST_F (ExprEvalTest, ArraySubscriptPgFirstElement) {
721+ // ARRAY[10, 20, 30][1] with PostgreSQL -> 10
722+ AstNode* arr = make_node (arena, NodeType::NODE_ARRAY_CONSTRUCTOR);
723+ arr->add_child (leaf (NodeType::NODE_LITERAL_INT, " 10" ));
724+ arr->add_child (leaf (NodeType::NODE_LITERAL_INT, " 20" ));
725+ arr->add_child (leaf (NodeType::NODE_LITERAL_INT, " 30" ));
726+
727+ AstNode* subscript = make_node (arena, NodeType::NODE_ARRAY_SUBSCRIPT);
728+ subscript->add_child (arr);
729+ subscript->add_child (leaf (NodeType::NODE_LITERAL_INT, " 1" ));
730+
731+ auto v = eval_pg (subscript);
732+ EXPECT_EQ (v.tag , Value::TAG_INT64);
733+ EXPECT_EQ (v.int_val , 10 );
734+ }
735+
736+ TEST_F (ExprEvalTest, ArraySubscriptOutOfBounds) {
737+ // ARRAY[10, 20][5] -> null
738+ AstNode* arr = make_node (arena, NodeType::NODE_ARRAY_CONSTRUCTOR);
739+ arr->add_child (leaf (NodeType::NODE_LITERAL_INT, " 10" ));
740+ arr->add_child (leaf (NodeType::NODE_LITERAL_INT, " 20" ));
741+
742+ AstNode* subscript = make_node (arena, NodeType::NODE_ARRAY_SUBSCRIPT);
743+ subscript->add_child (arr);
744+ subscript->add_child (leaf (NodeType::NODE_LITERAL_INT, " 5" ));
745+
746+ EXPECT_TRUE (eval_pg (subscript).is_null ());
747+ }
748+
749+ TEST_F (ExprEvalTest, ArraySubscriptPgZeroOutOfBounds) {
750+ // ARRAY[10, 20][0] with PostgreSQL -> null (1-based, so 0 is out of bounds)
751+ AstNode* arr = make_node (arena, NodeType::NODE_ARRAY_CONSTRUCTOR);
752+ arr->add_child (leaf (NodeType::NODE_LITERAL_INT, " 10" ));
753+ arr->add_child (leaf (NodeType::NODE_LITERAL_INT, " 20" ));
754+
755+ AstNode* subscript = make_node (arena, NodeType::NODE_ARRAY_SUBSCRIPT);
756+ subscript->add_child (arr);
757+ subscript->add_child (leaf (NodeType::NODE_LITERAL_INT, " 0" ));
758+
759+ EXPECT_TRUE (eval_pg (subscript).is_null ());
760+ }
761+
762+ TEST_F (ExprEvalTest, ArraySubscriptPgStringElements) {
763+ // ARRAY['hello', 'world'][1] with PostgreSQL -> 'hello'
764+ AstNode* arr = make_node (arena, NodeType::NODE_ARRAY_CONSTRUCTOR);
765+ arr->add_child (leaf (NodeType::NODE_LITERAL_STRING, " hello" ));
766+ arr->add_child (leaf (NodeType::NODE_LITERAL_STRING, " world" ));
767+
768+ AstNode* subscript = make_node (arena, NodeType::NODE_ARRAY_SUBSCRIPT);
769+ subscript->add_child (arr);
770+ subscript->add_child (leaf (NodeType::NODE_LITERAL_INT, " 1" ));
771+
772+ auto v = eval_pg (subscript);
773+ EXPECT_EQ (v.tag , Value::TAG_STRING);
774+ EXPECT_EQ (std::string (v.str_val .ptr , v.str_val .len ), " hello" );
775+ }
776+
777+ TEST_F (ExprEvalTest, ArraySubscriptNullIndex) {
778+ // ARRAY[10, 20][NULL] -> null
779+ AstNode* arr = make_node (arena, NodeType::NODE_ARRAY_CONSTRUCTOR);
780+ arr->add_child (leaf (NodeType::NODE_LITERAL_INT, " 10" ));
781+ arr->add_child (leaf (NodeType::NODE_LITERAL_INT, " 20" ));
782+
783+ AstNode* subscript = make_node (arena, NodeType::NODE_ARRAY_SUBSCRIPT);
784+ subscript->add_child (arr);
785+ subscript->add_child (make_node (arena, NodeType::NODE_LITERAL_NULL));
786+
787+ EXPECT_TRUE (eval_pg (subscript).is_null ());
788+ }
789+
790+ TEST_F (ExprEvalTest, ArraySubscriptNoChildren) {
791+ // Malformed: no children -> null
792+ AstNode* subscript = make_node (arena, NodeType::NODE_ARRAY_SUBSCRIPT);
793+ EXPECT_TRUE (eval_pg (subscript).is_null ());
794+ }
795+
796+ TEST_F (ExprEvalTest, ArraySubscriptMysql0Based) {
797+ // MySQL uses 0-based indexing: ARRAY[10, 20, 30][0] -> 10
798+ AstNode* arr = make_node (arena, NodeType::NODE_ARRAY_CONSTRUCTOR);
799+ arr->add_child (leaf (NodeType::NODE_LITERAL_INT, " 10" ));
800+ arr->add_child (leaf (NodeType::NODE_LITERAL_INT, " 20" ));
801+ arr->add_child (leaf (NodeType::NODE_LITERAL_INT, " 30" ));
802+
803+ AstNode* subscript = make_node (arena, NodeType::NODE_ARRAY_SUBSCRIPT);
804+ subscript->add_child (arr);
805+ subscript->add_child (leaf (NodeType::NODE_LITERAL_INT, " 0" ));
806+
807+ auto v = eval_mysql (subscript);
808+ EXPECT_EQ (v.tag , Value::TAG_INT64);
809+ EXPECT_EQ (v.int_val , 10 );
810+ }
0 commit comments