已合并
修复lower_case_table_names导致升级失败的问题 #2366
chenxiaobin19创建于 2月5日
修复lower_case_table_names导致升级失败的问题 #2366
已合并
共 19 个文件变更+797-645
| @@ -55,7 +55,7 @@ PARTITION BY RANGE (c1) SUBPARTITION BY RANGE (c2) | |||
| 55 | select CONSTRAINT_CATALOG,CONSTRAINT_SCHEMA,CONSTRAINT_NAME,TABLE_SCHEMA,TABLE_NAME,CONSTRAINT_TYPE,ENFORCED from information_schema.table_constraints order by 1,2,3,4 limit 1; | 55 | select CONSTRAINT_CATALOG,CONSTRAINT_SCHEMA,CONSTRAINT_NAME,TABLE_SCHEMA,TABLE_NAME,CONSTRAINT_TYPE,ENFORCED from information_schema.table_constraints order by 1,2,3,4 limit 1; |
| 56 | CONSTRAINT_CATALOG | CONSTRAINT_SCHEMA | CONSTRAINT_NAME | TABLE_SCHEMA | TABLE_NAME | CONSTRAINT_TYPE | ENFORCED | 56 | CONSTRAINT_CATALOG | CONSTRAINT_SCHEMA | CONSTRAINT_NAME | TABLE_SCHEMA | TABLE_NAME | CONSTRAINT_TYPE | ENFORCED |
| 57 | --------------------+-------------------+-----------------------+--------------+---------------+-----------------+---------- | 57 | --------------------+-------------------+-----------------------+--------------+---------------+-----------------+---------- |
| 58 | - contrib_regression | coverage | 4994_13130_1_not_null | coverage | proc_coverage | CHECK | YES | 58 | + contrib_regression | coverage | 4994_13141_1_not_null | coverage | proc_coverage | CHECK | YES |
| 59 | (1 row) | 59 | (1 row) |
| 60 | 60 | ||
| 61 | select CHARACTER_SET_NAME,DEFAULT_COLLATE_NAME,DESCRIPTION,MAXLEN from INFORMATION_SCHEMA.CHARACTER_SETS order by 1,2,3,4 limit 1; | 61 | select CHARACTER_SET_NAME,DEFAULT_COLLATE_NAME,DESCRIPTION,MAXLEN from INFORMATION_SCHEMA.CHARACTER_SETS order by 1,2,3,4 limit 1; |
| @@ -67,7 +67,7 @@ select CHARACTER_SET_NAME,DEFAULT_COLLATE_NAME,DESCRIPTION,MAXLEN from INFORMATI | |||
| 67 | select CONSTRAINT_CATALOG,CONSTRAINT_SCHEMA,CONSTRAINT_NAME,CHECK_CLAUSE FROM INFORMATION_SCHEMA.CHECK_CONSTRAINTS order by 1,2,3,4 limit 1; | 67 | select CONSTRAINT_CATALOG,CONSTRAINT_SCHEMA,CONSTRAINT_NAME,CHECK_CLAUSE FROM INFORMATION_SCHEMA.CHECK_CONSTRAINTS order by 1,2,3,4 limit 1; |
| 68 | CONSTRAINT_CATALOG | CONSTRAINT_SCHEMA | CONSTRAINT_NAME | CHECK_CLAUSE | 68 | CONSTRAINT_CATALOG | CONSTRAINT_SCHEMA | CONSTRAINT_NAME | CHECK_CLAUSE |
| 69 | --------------------+-------------------+-----------------------+------------------------- | 69 | --------------------+-------------------+-----------------------+------------------------- |
| 70 | - contrib_regression | coverage | 4994_13130_1_not_null | coverage_id IS NOT NULL | 70 | + contrib_regression | coverage | 4994_13141_1_not_null | coverage_id IS NOT NULL |
| 71 | (1 row) | 71 | (1 row) |
| 72 | 72 | ||
| 73 | select COLLATION_NAME,CHARACTER_SET_NAME,ID,IS_DEFAULT,IS_COMPILED,SORTLEN,PAD_ATTRIBUTE from INFORMATION_SCHEMA.COLLATIONS order by 1,2,3,4 limit 1; | 73 | select COLLATION_NAME,CHARACTER_SET_NAME,ID,IS_DEFAULT,IS_COMPILED,SORTLEN,PAD_ATTRIBUTE from INFORMATION_SCHEMA.COLLATIONS order by 1,2,3,4 limit 1; |
| @@ -1445,3 +1445,10 @@ select count(*) from table_json_a,table_json_b group by | |||
| 1445 | drop table table_json_a; | 1445 | drop table table_json_a; |
| 1446 | drop table table_json_b; | 1446 | drop table table_json_b; |
| 1447 | drop table t1; | 1447 | drop table t1; |
| 1448 | +set dolphin.lower_case_table_names = 0; | ||
| 1449 | +select S.type from gs_get_hba_conf() S limit 1; | ||
| 1450 | + type | ||
| 1451 | +------- | ||
| 1452 | + local | ||
| 1453 | +(1 row) | ||
| 1454 | + | ||
| @@ -6497,6 +6497,10 @@ | |||
| 6497 | "jsonb_array_length", 1, | 6497 | "jsonb_array_length", 1, |
| 6498 | AddBuiltinFunc(_0(3416), _1("jsonb_array_length"), _2(1), _3(true), _4(false), _5(jsonb_array_length), _6(23), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 3802), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("jsonb_array_length"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(false), _32(false), _33(NULL), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) | 6498 | AddBuiltinFunc(_0(3416), _1("jsonb_array_length"), _2(1), _3(true), _4(false), _5(jsonb_array_length), _6(23), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 3802), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("jsonb_array_length"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(false), _32(false), _33(NULL), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) |
| 6499 | ), | 6499 | ), |
| 6500 | + AddFuncGroup( | ||
| 6501 | + "jsonb_bool", 1, | ||
| 6502 | + AddBuiltinFunc(_0(3365), _1("jsonb_bool"), _2(1), _3(true), _4(false), _5(jsonb_bool), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(0), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 3802), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("jsonb_bool"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(false), _32(false), _33(NULL), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) | ||
| 6503 | + ), | ||
| 6500 | AddFuncGroup( | 6504 | AddFuncGroup( |
| 6501 | "jsonb_cmp", 1, | 6505 | "jsonb_cmp", 1, |
| 6502 | AddBuiltinFunc(_0(3417), _1("jsonb_cmp"), _2(2), _3(true), _4(false), _5(jsonb_cmp), _6(23), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 3802, 3802), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("jsonb_cmp"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(false), _32(false), _33(NULL), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) | 6506 | AddBuiltinFunc(_0(3417), _1("jsonb_cmp"), _2(2), _3(true), _4(false), _5(jsonb_cmp), _6(23), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 3802, 3802), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("jsonb_cmp"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(false), _32(false), _33(NULL), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) |
| @@ -6513,6 +6517,10 @@ | |||
| 6513 | "jsonb_contains", 1, | 6517 | "jsonb_contains", 1, |
| 6514 | AddBuiltinFunc(_0(3418), _1("jsonb_contains"), _2(2), _3(true), _4(false), _5(jsonb_contains), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 3802, 3802), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("jsonb_contains"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(false), _32(false), _33(NULL), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) | 6518 | AddBuiltinFunc(_0(3418), _1("jsonb_contains"), _2(2), _3(true), _4(false), _5(jsonb_contains), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 3802, 3802), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("jsonb_contains"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(false), _32(false), _33(NULL), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) |
| 6515 | ), | 6519 | ), |
| 6520 | + AddFuncGroup( | ||
| 6521 | + "jsonb_date", 1, | ||
| 6522 | + AddBuiltinFunc(_0(3373), _1("jsonb_date"), _2(1), _3(true), _4(false), _5(jsonb_date), _6(1082), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(0), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 3802), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("jsonb_date"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(false), _32(false), _33(NULL), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) | ||
| 6523 | + ), | ||
| 6516 | AddFuncGroup( | 6524 | AddFuncGroup( |
| 6517 | "jsonb_delete", 3, | 6525 | "jsonb_delete", 3, |
| 6518 | AddBuiltinFunc(_0(5612), _1("jsonb_delete"), _2(2), _3(true), _4(false), _5(jsonb_delete_idx), _6(3802), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 3802, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("jsonb_delete_idx"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(false), _32(false), _33(NULL), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)), | 6526 | AddBuiltinFunc(_0(5612), _1("jsonb_delete"), _2(2), _3(true), _4(false), _5(jsonb_delete_idx), _6(3802), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 3802, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("jsonb_delete_idx"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(false), _32(false), _33(NULL), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)), |
| @@ -6559,6 +6567,14 @@ | |||
| 6559 | "jsonb_extract_path_text_op", 1, | 6567 | "jsonb_extract_path_text_op", 1, |
| 6560 | AddBuiltinFunc(_0(3427), _1("jsonb_extract_path_text_op"), _2(2), _3(true), _4(false), _5(jsonb_extract_path_text), _6(25), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 3802, 1009), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("jsonb_extract_path_text"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(false), _32(false), _33(NULL), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) | 6568 | AddBuiltinFunc(_0(3427), _1("jsonb_extract_path_text_op"), _2(2), _3(true), _4(false), _5(jsonb_extract_path_text), _6(25), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 3802, 1009), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("jsonb_extract_path_text"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(false), _32(false), _33(NULL), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) |
| 6561 | ), | 6569 | ), |
| 6570 | + AddFuncGroup( | ||
| 6571 | + "jsonb_float4", 1, | ||
| 6572 | + AddBuiltinFunc(_0(3371), _1("jsonb_float4"), _2(1), _3(true), _4(false), _5(jsonb_float4), _6(700), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(0), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 3802), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("jsonb_float4"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(false), _32(false), _33(NULL), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) | ||
| 6573 | + ), | ||
| 6574 | + AddFuncGroup( | ||
| 6575 | + "jsonb_float8", 1, | ||
| 6576 | + AddBuiltinFunc(_0(3372), _1("jsonb_float8"), _2(1), _3(true), _4(false), _5(jsonb_float8), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(0), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 3802), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("jsonb_float8"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(false), _32(false), _33(NULL), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) | ||
| 6577 | + ), | ||
| 6562 | AddFuncGroup( | 6578 | AddFuncGroup( |
| 6563 | "jsonb_ge", 1, | 6579 | "jsonb_ge", 1, |
| 6564 | AddBuiltinFunc(_0(3428), _1("jsonb_ge"), _2(2), _3(true), _4(false), _5(jsonb_ge), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 3802, 3802), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("jsonb_ge"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(false), _32(false), _33(NULL), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) | 6580 | AddBuiltinFunc(_0(3428), _1("jsonb_ge"), _2(2), _3(true), _4(false), _5(jsonb_ge), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 3802, 3802), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("jsonb_ge"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(false), _32(false), _33(NULL), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) |
| @@ -6579,6 +6595,22 @@ | |||
| 6579 | "jsonb_insert", 1, | 6595 | "jsonb_insert", 1, |
| 6580 | AddBuiltinFunc(_0(5610), _1("jsonb_insert"), _2(4), _3(true), _4(false), _5(jsonb_insert), _6(3802), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(1), _20(4, 3802, 1009, 3802, 16), _21(NULL), _22(NULL), _23(NULL), _24("({CONST :consttype 16 :consttypmod -1 :constcollid 0 :constlen 1 :constbyval true :constisnull false :ismaxvalue false :location 72803 :constvalue 1 [ 0 0 0 0 0 0 0 0 ] :cursor_data :row_count 0 :cur_dno 0 :is_open false :found false :not_found false :null_open false :null_fetch false})"), _25("jsonb_insert"), _26(NULL), _27(NULL), _28(NULL), _29(1, 3), _30(false), _31(false), _32(false), _33(NULL), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) | 6596 | AddBuiltinFunc(_0(5610), _1("jsonb_insert"), _2(4), _3(true), _4(false), _5(jsonb_insert), _6(3802), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(1), _20(4, 3802, 1009, 3802, 16), _21(NULL), _22(NULL), _23(NULL), _24("({CONST :consttype 16 :consttypmod -1 :constcollid 0 :constlen 1 :constbyval true :constisnull false :ismaxvalue false :location 72803 :constvalue 1 [ 0 0 0 0 0 0 0 0 ] :cursor_data :row_count 0 :cur_dno 0 :is_open false :found false :not_found false :null_open false :null_fetch false})"), _25("jsonb_insert"), _26(NULL), _27(NULL), _28(NULL), _29(1, 3), _30(false), _31(false), _32(false), _33(NULL), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) |
| 6581 | ), | 6597 | ), |
| 6598 | + AddFuncGroup( | ||
| 6599 | + "jsonb_int1", 1, | ||
| 6600 | + AddBuiltinFunc(_0(3366), _1("jsonb_int1"), _2(1), _3(true), _4(false), _5(jsonb_int1), _6(5545), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(0), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 3802), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("jsonb_int1"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(false), _32(false), _33(NULL), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) | ||
| 6601 | + ), | ||
| 6602 | + AddFuncGroup( | ||
| 6603 | + "jsonb_int2", 1, | ||
| 6604 | + AddBuiltinFunc(_0(3367), _1("jsonb_int2"), _2(1), _3(true), _4(false), _5(jsonb_int2), _6(21), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(0), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 3802), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("jsonb_int2"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(false), _32(false), _33(NULL), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) | ||
| 6605 | + ), | ||
| 6606 | + AddFuncGroup( | ||
| 6607 | + "jsonb_int4", 1, | ||
| 6608 | + AddBuiltinFunc(_0(3368), _1("jsonb_int4"), _2(1), _3(true), _4(false), _5(jsonb_int4), _6(23), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(0), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 3802), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("jsonb_int4"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(false), _32(false), _33(NULL), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) | ||
| 6609 | + ), | ||
| 6610 | + AddFuncGroup( | ||
| 6611 | + "jsonb_int8", 1, | ||
| 6612 | + AddBuiltinFunc(_0(3369), _1("jsonb_int8"), _2(1), _3(true), _4(false), _5(jsonb_int8), _6(20), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(0), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 3802), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("jsonb_int8"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(false), _32(false), _33(NULL), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) | ||
| 6613 | + ), | ||
| 6582 | AddFuncGroup( | 6614 | AddFuncGroup( |
| 6583 | "jsonb_le", 1, | 6615 | "jsonb_le", 1, |
| 6584 | AddBuiltinFunc(_0(3431), _1("jsonb_le"), _2(2), _3(true), _4(false), _5(jsonb_le), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 3802, 3802), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("jsonb_le"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(false), _32(false), _33(NULL), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) | 6616 | AddBuiltinFunc(_0(3431), _1("jsonb_le"), _2(2), _3(true), _4(false), _5(jsonb_le), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 3802, 3802), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("jsonb_le"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(false), _32(false), _33(NULL), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) |
| @@ -6591,6 +6623,10 @@ | |||
| 6591 | "jsonb_ne", 1, | 6623 | "jsonb_ne", 1, |
| 6592 | AddBuiltinFunc(_0(3432), _1("jsonb_ne"), _2(2), _3(true), _4(false), _5(jsonb_ne), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 3802, 3802), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("jsonb_ne"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(false), _32(false), _33(NULL), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) | 6624 | AddBuiltinFunc(_0(3432), _1("jsonb_ne"), _2(2), _3(true), _4(false), _5(jsonb_ne), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 3802, 3802), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("jsonb_ne"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(false), _32(false), _33(NULL), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) |
| 6593 | ), | 6625 | ), |
| 6626 | + AddFuncGroup( | ||
| 6627 | + "jsonb_numeric", 1, | ||
| 6628 | + AddBuiltinFunc(_0(3370), _1("jsonb_numeric"), _2(1), _3(true), _4(false), _5(jsonb_numeric), _6(1700), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(0), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 3802), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("jsonb_numeric"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(false), _32(false), _33(NULL), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) | ||
| 6629 | + ), | ||
| 6594 | AddFuncGroup( | 6630 | AddFuncGroup( |
| 6595 | "jsonb_object_field", 1, | 6631 | "jsonb_object_field", 1, |
| 6596 | AddBuiltinFunc(_0(3433), _1("jsonb_object_field"), _2(2), _3(true), _4(false), _5(jsonb_object_field), _6(3802), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 3802, 25), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("jsonb_object_field"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(false), _32(false), _33(NULL), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) | 6632 | AddBuiltinFunc(_0(3433), _1("jsonb_object_field"), _2(2), _3(true), _4(false), _5(jsonb_object_field), _6(3802), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 3802, 25), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("jsonb_object_field"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(false), _32(false), _33(NULL), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) |
| @@ -6607,6 +6643,14 @@ | |||
| 6607 | "jsonb_out", 1, | 6643 | "jsonb_out", 1, |
| 6608 | AddBuiltinFunc(_0(3436), _1("jsonb_out"), _2(1), _3(true), _4(false), _5(jsonb_out), _6(2275), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 3802), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("jsonb_out"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(false), _32(false), _33(NULL), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) | 6644 | AddBuiltinFunc(_0(3436), _1("jsonb_out"), _2(1), _3(true), _4(false), _5(jsonb_out), _6(2275), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 3802), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("jsonb_out"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(false), _32(false), _33(NULL), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) |
| 6609 | ), | 6645 | ), |
| 6646 | + AddFuncGroup( | ||
| 6647 | + "jsonb_path_exists", 1, | ||
| 6648 | + AddBuiltinFunc(_0(4055), _1("jsonb_path_exists"), _2(4), _3(true), _4(false), _5(jsonb_path_exists), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(2), _20(4, 3802, 4072, 3802, 16), _21(NULL), _22(NULL), _23(4, "target", "path", "vars", "silent"), _24("({CONST :consttype 3802 :consttypmod -1 :constcollid 0 :constlen -1 :constbyval false :constisnull false :ismaxvalue false :location 99 :constvalue 8 [ 32 0 0 0 0 0 0 32 ] :cursor_data :row_count 0 :cur_dno -1 :is_open false :found false :not_found false :null_open false :null_fetch false} {CONST :consttype 16 :consttypmod -1 :constcollid 0 :constlen 1 :constbyval true :constisnull false :ismaxvalue false :location 139 :constvalue 1 [ 0 0 0 0 0 0 0 0 ] :cursor_data :row_count 0 :cur_dno -1 :is_open false :found false :not_found false :null_open false :null_fetch false})"), _25("jsonb_path_exists"), _26(NULL), _27(NULL), _28(NULL), _29(2, 2, 3), _30(false), _31(false), _32(false), _33(NULL), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) | ||
| 6649 | + ), | ||
| 6650 | + AddFuncGroup( | ||
| 6651 | + "jsonb_path_query_first", 1, | ||
| 6652 | + AddBuiltinFunc(_0(4056), _1("jsonb_path_query_first"), _2(4), _3(true), _4(false), _5(jsonb_path_query_first), _6(3802), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(2), _20(4, 3802, 4072, 3802, 16), _21(NULL), _22(NULL), _23(4, "target", "path", "vars", "silent"), _24("({CONST :consttype 3802 :consttypmod -1 :constcollid 0 :constlen -1 :constbyval false :constisnull false :ismaxvalue false :location 104 :constvalue 8 [ 32 0 0 0 0 0 0 32 ] :cursor_data :row_count 0 :cur_dno -1 :is_open false :found false :not_found false :null_open false :null_fetch false} {CONST :consttype 16 :consttypmod -1 :constcollid 0 :constlen 1 :constbyval true :constisnull false :ismaxvalue false :location 144 :constvalue 1 [ 0 0 0 0 0 0 0 0 ] :cursor_data :row_count 0 :cur_dno -1 :is_open false :found false :not_found false :null_open false :null_fetch false})"), _25("jsonb_path_query_first"), _26(NULL), _27(NULL), _28(NULL), _29(2, 2, 3), _30(false), _31(false), _32(false), _33(NULL), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) | ||
| 6653 | + ), | ||
| 6610 | AddFuncGroup( | 6654 | AddFuncGroup( |
| 6611 | "jsonb_populate_record", 1, | 6655 | "jsonb_populate_record", 1, |
| 6612 | AddBuiltinFunc(_0(3437), _1("jsonb_populate_record"), _2(3), _3(false), _4(false), _5(jsonb_populate_record), _6(2283), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(1), _20(3, 2283, 3802, 16), _21(NULL), _22(NULL), _23(NULL), _24("({CONST :consttype 16 :consttypmod -1 :constcollid 0 :constlen 1 :constbyval true :constisnull false :ismaxvalue false :location 72803 :constvalue 1 [ 0 0 0 0 0 0 0 0 ] :cursor_data :row_count 0 :cur_dno 0 :is_open false :found false :not_found false :null_open false :null_fetch false})"), _25("jsonb_populate_record"), _26(NULL), _27(NULL), _28(NULL), _29(1, 2), _30(false), _31(false), _32(false), _33(NULL), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) | 6656 | AddBuiltinFunc(_0(3437), _1("jsonb_populate_record"), _2(3), _3(false), _4(false), _5(jsonb_populate_record), _6(2283), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(1), _20(3, 2283, 3802, 16), _21(NULL), _22(NULL), _23(NULL), _24("({CONST :consttype 16 :consttypmod -1 :constcollid 0 :constlen 1 :constbyval true :constisnull false :ismaxvalue false :location 72803 :constvalue 1 [ 0 0 0 0 0 0 0 0 ] :cursor_data :row_count 0 :cur_dno 0 :is_open false :found false :not_found false :null_open false :null_fetch false})"), _25("jsonb_populate_record"), _26(NULL), _27(NULL), _28(NULL), _29(1, 2), _30(false), _31(false), _32(false), _33(NULL), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) |
| @@ -6627,10 +6671,34 @@ | |||
| 6627 | "jsonb_set", 1, | 6671 | "jsonb_set", 1, |
| 6628 | AddBuiltinFunc(_0(5611), _1("jsonb_set"), _2(4), _3(true), _4(false), _5(jsonb_set), _6(3802), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(1), _20(4, 3802, 1009, 3802, 16), _21(NULL), _22(NULL), _23(NULL), _24("({CONST :consttype 16 :consttypmod -1 :constcollid 0 :constlen 1 :constbyval true :constisnull false :ismaxvalue false :location 72803 :constvalue 1 [ 0 0 0 0 0 0 0 0 ] :cursor_data :row_count 0 :cur_dno 0 :is_open false :found false :not_found false :null_open false :null_fetch false})"), _25("jsonb_set"), _26(NULL), _27(NULL), _28(NULL), _29(1, 3), _30(false), _31(false), _32(false), _33(NULL), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) | 6672 | AddBuiltinFunc(_0(5611), _1("jsonb_set"), _2(4), _3(true), _4(false), _5(jsonb_set), _6(3802), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(1), _20(4, 3802, 1009, 3802, 16), _21(NULL), _22(NULL), _23(NULL), _24("({CONST :consttype 16 :consttypmod -1 :constcollid 0 :constlen 1 :constbyval true :constisnull false :ismaxvalue false :location 72803 :constvalue 1 [ 0 0 0 0 0 0 0 0 ] :cursor_data :row_count 0 :cur_dno 0 :is_open false :found false :not_found false :null_open false :null_fetch false})"), _25("jsonb_set"), _26(NULL), _27(NULL), _28(NULL), _29(1, 3), _30(false), _31(false), _32(false), _33(NULL), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) |
| 6629 | ), | 6673 | ), |
| 6674 | + AddFuncGroup( | ||
| 6675 | + "jsonb_time", 1, | ||
| 6676 | + AddBuiltinFunc(_0(3374), _1("jsonb_time"), _2(1), _3(true), _4(false), _5(jsonb_time), _6(1083), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(0), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 3802), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("jsonb_time"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(false), _32(false), _33(NULL), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) | ||
| 6677 | + ), | ||
| 6678 | + AddFuncGroup( | ||
| 6679 | + "jsonb_timestamp", 1, | ||
| 6680 | + AddBuiltinFunc(_0(3375), _1("jsonb_timestamp"), _2(1), _3(true), _4(false), _5(jsonb_timestamp), _6(1114), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(0), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 3802), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("jsonb_timestamp"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(false), _32(false), _33(NULL), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) | ||
| 6681 | + ), | ||
| 6630 | AddFuncGroup( | 6682 | AddFuncGroup( |
| 6631 | "jsonb_typeof", 1, | 6683 | "jsonb_typeof", 1, |
| 6632 | AddBuiltinFunc(_0(3445), _1("jsonb_typeof"), _2(1), _3(true), _4(false), _5(jsonb_typeof), _6(25), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 3802), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("jsonb_typeof"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(false), _32(false), _33(NULL), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) | 6684 | AddBuiltinFunc(_0(3445), _1("jsonb_typeof"), _2(1), _3(true), _4(false), _5(jsonb_typeof), _6(25), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 3802), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("jsonb_typeof"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(false), _32(false), _33(NULL), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) |
| 6633 | ), | 6685 | ), |
| 6686 | + AddFuncGroup( | ||
| 6687 | + "jsonpath_in", 1, | ||
| 6688 | + AddBuiltinFunc(_0(4051), _1("jsonpath_in"), _2(1), _3(true), _4(false), _5(jsonpath_in), _6(4072), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 2275), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("jsonpath_in"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(false), _32(false), _33(NULL), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) | ||
| 6689 | + ), | ||
| 6690 | + AddFuncGroup( | ||
| 6691 | + "jsonpath_out", 1, | ||
| 6692 | + AddBuiltinFunc(_0(4053), _1("jsonpath_out"), _2(1), _3(true), _4(false), _5(jsonpath_out), _6(2275), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 4072), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("jsonpath_out"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(false), _32(false), _33(NULL), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) | ||
| 6693 | + ), | ||
| 6694 | + AddFuncGroup( | ||
| 6695 | + "jsonpath_recv", 1, | ||
| 6696 | + AddBuiltinFunc(_0(4052), _1("jsonpath_recv"), _2(1), _3(true), _4(false), _5(jsonpath_recv), _6(4072), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("jsonpath_recv"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(false), _32(false), _33(NULL), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) | ||
| 6697 | + ), | ||
| 6698 | + AddFuncGroup( | ||
| 6699 | + "jsonpath_send", 1, | ||
| 6700 | + AddBuiltinFunc(_0(4054), _1("jsonpath_send"), _2(1), _3(true), _4(false), _5(jsonpath_send), _6(17), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 4072), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("jsonpath_send"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(false), _32(false), _33(NULL), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) | ||
| 6701 | + ), | ||
| 6634 | AddFuncGroup( | 6702 | AddFuncGroup( |
| 6635 | "justify_days", 1, | 6703 | "justify_days", 1, |
| 6636 | AddBuiltinFunc(_0(1295), _1("justify_days"), _2(1), _3(true), _4(false), _5(interval_justify_days), _6(1186), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 1186), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("interval_justify_days"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("promote groups of 30 days to numbers of months"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) | 6704 | AddBuiltinFunc(_0(1295), _1("justify_days"), _2(1), _3(true), _4(false), _5(interval_justify_days), _6(1186), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 1186), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("interval_justify_days"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("promote groups of 30 days to numbers of months"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) |
| @@ -73,9 +73,6 @@ extern void DropCastById(Oid castOid); | |||
| 73 | extern ObjectAddress AlterFunctionNamespace(List* name, List* argtypes, bool isagg, const char* newschema); | 73 | extern ObjectAddress AlterFunctionNamespace(List* name, List* argtypes, bool isagg, const char* newschema); |
| 74 | extern Oid AlterFunctionNamespace_oid(Oid procOid, Oid nspOid); | 74 | extern Oid AlterFunctionNamespace_oid(Oid procOid, Oid nspOid); |
| 75 | extern void ExecuteDoStmt(DoStmt* stmt, bool atomic); | 75 | extern void ExecuteDoStmt(DoStmt* stmt, bool atomic); |
| 76 | -#ifdef DOLPHIN | ||
| 77 | -extern void ExecuteCallStmt(DolphinCallStmt *stmt, ParamListInfo params, bool atomic); | ||
| 78 | -#endif | ||
| 79 | extern Oid get_cast_oid(Oid sourcetypeid, Oid targettypeid, bool missing_ok); | 76 | extern Oid get_cast_oid(Oid sourcetypeid, Oid targettypeid, bool missing_ok); |
| 80 | extern void IsThereFunctionInNamespace(const char *proname, int pronargs, oidvector *proargtypes, Oid nspOid); | 77 | extern void IsThereFunctionInNamespace(const char *proname, int pronargs, oidvector *proargtypes, Oid nspOid); |
| 81 | 78 | ||
| @@ -231,6 +228,8 @@ extern void DropEventCommand(DropEventStmt* stmt); | |||
| 231 | extern char* parseIntervalExprString(Node *intervalNode); | 228 | extern char* parseIntervalExprString(Node *intervalNode); |
| 232 | extern char* parseTimeExprString(Node* timeExpr); | 229 | extern char* parseTimeExprString(Node* timeExpr); |
| 233 | 230 | ||
| 231 | +extern void ExecuteCallStmt(DolphinCallStmt *stmt, ParamListInfo params, bool atomic, DestReceiver *dest = NULL); | ||
| 232 | + | ||
| 234 | #endif /* !FRONTEND_PARSER */ | 233 | #endif /* !FRONTEND_PARSER */ |
| 235 | extern DefElem* defWithOids(bool value); | 234 | extern DefElem* defWithOids(bool value); |
| 236 | #endif /* DEFREM_H */ | 235 | #endif /* DEFREM_H */ |
| @@ -26,6 +26,8 @@ extern void get_keys_order(char **a, int l, int r, int pos[]); | |||
| 26 | extern Datum json_path_exists(PG_FUNCTION_ARGS); | 26 | extern Datum json_path_exists(PG_FUNCTION_ARGS); |
| 27 | extern Datum json_textcontains(PG_FUNCTION_ARGS); | 27 | extern Datum json_textcontains(PG_FUNCTION_ARGS); |
| 28 | extern Datum json_textcontains_text(PG_FUNCTION_ARGS); | 28 | extern Datum json_textcontains_text(PG_FUNCTION_ARGS); |
| 29 | +extern Datum jsonb_path_exists(PG_FUNCTION_ARGS); | ||
| 30 | +extern Datum jsonb_path_query_first(PG_FUNCTION_ARGS); | ||
| 29 | 31 | ||
| 30 | extern int json_typeof_internal(text* json); | 32 | extern int json_typeof_internal(text* json); |
| 31 | 33 | ||
| @@ -202,7 +202,8 @@ enum PLpgSQL_stmt_types { | |||
| 202 | PLPGSQL_STMT_SAVEPOINT, | 202 | PLPGSQL_STMT_SAVEPOINT, |
| 203 | PLPGSQL_STMT_SIGNAL, | 203 | PLPGSQL_STMT_SIGNAL, |
| 204 | PLPGSQL_STMT_RESIGNAL, | 204 | PLPGSQL_STMT_RESIGNAL, |
| 205 | - PLPGSQL_STMT_PIPE_ROW | 205 | + PLPGSQL_STMT_PIPE_ROW, |
| 206 | + PLPGSQL_STMT_EXEC | ||
| 206 | }; | 207 | }; |
| 207 | 208 | ||
| 208 | /* ---------- | 209 | /* ---------- |
| @@ -1080,6 +1081,26 @@ typedef struct { | |||
| 1080 | char* sqlString; | 1081 | char* sqlString; |
| 1081 | } PLpgSQL_stmt_pipe_row; | 1082 | } PLpgSQL_stmt_pipe_row; |
| 1082 | 1083 | ||
| 1084 | +typedef struct { | ||
| 1085 | + int cmd_type; | ||
| 1086 | + int lineno; | ||
| 1087 | + PLpgSQL_expr *expr; | ||
| 1088 | + bool is_call; | ||
| 1089 | + PLpgSQL_variable *target; | ||
| 1090 | + int returnCodeDno; | ||
| 1091 | + int paramno; | ||
| 1092 | + List *params; | ||
| 1093 | + bool isScalarFunc; | ||
| 1094 | +} PLpgSQL_stmt_exec; | ||
| 1095 | + | ||
| 1096 | +typedef struct | ||
| 1097 | +{ | ||
| 1098 | + const char *name; | ||
| 1099 | + PLpgSQL_expr *expr; | ||
| 1100 | + char mode; | ||
| 1101 | + int varno; /* dno of the output variable */ | ||
| 1102 | +} PLpgSQL_exec_param; | ||
| 1103 | + | ||
| 1083 | typedef struct { /* RAISE statement */ | 1104 | typedef struct { /* RAISE statement */ |
| 1084 | int cmd_type; | 1105 | int cmd_type; |
| 1085 | int lineno; | 1106 | int lineno; |
| @@ -1328,6 +1349,7 @@ typedef struct PLpgSQL_function { /* Complete compiled function */ | |||
| 1328 | Oid namespaceOid; | 1349 | Oid namespaceOid; |
| 1329 | bool is_pipelined; | 1350 | bool is_pipelined; |
| 1330 | bool pipelined_resistuple; | 1351 | bool pipelined_resistuple; |
| 1352 | + bool is_itvf; | ||
| 1331 | } PLpgSQL_function; | 1353 | } PLpgSQL_function; |
| 1332 | 1354 | ||
| 1333 | class AutonomousSession; | 1355 | class AutonomousSession; |
| @@ -433,7 +433,6 @@ drop function alter_function_004; | |||
| 433 | drop function alter_function_005; | 433 | drop function alter_function_005; |
| 434 | drop function alter_function_006; | 434 | drop function alter_function_006; |
| 435 | drop function alter_function_007; | 435 | drop function alter_function_007; |
| 436 | --- security definer function not allow alter owner | ||
| 437 | \! @abs_bindir@/gs_restore -d restore_function_db -p @portstring@ @abs_bindir@/dump_function.tar >/dev/null 2>&1; echo $? | 436 | \! @abs_bindir@/gs_restore -d restore_function_db -p @portstring@ @abs_bindir@/dump_function.tar >/dev/null 2>&1; echo $? |
| 438 | \c restore_function_db | 437 | \c restore_function_db |
| 439 | 438 | ||
| @@ -407,7 +407,6 @@ drop procedure alter_procedure_004; | |||
| 407 | drop procedure alter_procedure_005; | 407 | drop procedure alter_procedure_005; |
| 408 | drop procedure alter_procedure_006; | 408 | drop procedure alter_procedure_006; |
| 409 | drop procedure alter_procedure_007; | 409 | drop procedure alter_procedure_007; |
| 410 | --- security definer function not allow alter owner | ||
| 411 | \! @abs_bindir@/gs_restore -d restore_procedure_db -p @portstring@ @abs_bindir@/dump_procedure.tar >/dev/null 2>&1; echo $? | 410 | \! @abs_bindir@/gs_restore -d restore_procedure_db -p @portstring@ @abs_bindir@/dump_procedure.tar >/dev/null 2>&1; echo $? |
| 412 | \c restore_procedure_db | 411 | \c restore_procedure_db |
| 413 | 412 | ||
| @@ -911,9 +911,8 @@ drop function alter_function_004; | |||
| 911 | drop function alter_function_005; | 911 | drop function alter_function_005; |
| 912 | drop function alter_function_006; | 912 | drop function alter_function_006; |
| 913 | drop function alter_function_007; | 913 | drop function alter_function_007; |
| 914 | --- security definer function not allow alter owner | ||
| 915 | \! @abs_bindir@/gs_restore -d restore_function_db -p @portstring@ @abs_bindir@/dump_function.tar >/dev/null 2>&1; echo $? | 914 | \! @abs_bindir@/gs_restore -d restore_function_db -p @portstring@ @abs_bindir@/dump_function.tar >/dev/null 2>&1; echo $? |
| 916 | -1 | 915 | +0 |
| 917 | \c restore_function_db | 916 | \c restore_function_db |
| 918 | show lc_collate; | 917 | show lc_collate; |
| 919 | lc_collate | 918 | lc_collate |
| @@ -826,9 +826,8 @@ drop procedure alter_procedure_004; | |||
| 826 | drop procedure alter_procedure_005; | 826 | drop procedure alter_procedure_005; |
| 827 | drop procedure alter_procedure_006; | 827 | drop procedure alter_procedure_006; |
| 828 | drop procedure alter_procedure_007; | 828 | drop procedure alter_procedure_007; |
| 829 | --- security definer function not allow alter owner | ||
| 830 | \! @abs_bindir@/gs_restore -d restore_procedure_db -p @portstring@ @abs_bindir@/dump_procedure.tar >/dev/null 2>&1; echo $? | 829 | \! @abs_bindir@/gs_restore -d restore_procedure_db -p @portstring@ @abs_bindir@/dump_procedure.tar >/dev/null 2>&1; echo $? |
| 831 | -1 | 830 | +0 |
| 832 | \c restore_procedure_db | 831 | \c restore_procedure_db |
| 833 | show lc_collate; | 832 | show lc_collate; |
| 834 | lc_collate | 833 | lc_collate |
| @@ -99,6 +99,9 @@ | |||
| 99 | #include "commands/comment.h" | 99 | #include "commands/comment.h" |
| 100 | #include "catalog/gs_dependencies_fn.h" | 100 | #include "catalog/gs_dependencies_fn.h" |
| 101 | #include "utils/sec_rls_utils.h" | 101 | #include "utils/sec_rls_utils.h" |
| 102 | + | ||
| 103 | +#include "utils/typcache.h" | ||
| 104 | +#include "nodes/makefuncs.h" | ||
| 102 | #ifdef DOLPHIN | 105 | #ifdef DOLPHIN |
| 103 | #include "plugin_commands/mysqlmode.h" | 106 | #include "plugin_commands/mysqlmode.h" |
| 104 | #endif | 107 | #endif |
| @@ -2573,6 +2576,36 @@ void AlterFunctionOwnerByPkg(Oid packageOid, Oid newOwnerId) | |||
| 2573 | heap_close(pg_proc_rel, NoLock); | 2576 | heap_close(pg_proc_rel, NoLock); |
| 2574 | } | 2577 | } |
| 2575 | 2578 | ||
| 2579 | +static void CheckAlterFunctionPrivileges(Oid newOwnerId, Oid procOid, bool isSecdef) | ||
| 2580 | +{ | ||
| 2581 | + bool enablePrivilegesSeparate = g_instance.attr.attr_security.enablePrivilegesSeparate; | ||
| 2582 | + | ||
| 2583 | + if (IsSystemObjOid(procOid) && u_sess->attr.attr_common.IsInplaceUpgrade == false) { | ||
| 2584 | + ereport(ERROR, | ||
| 2585 | + (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), | ||
| 2586 | + errmsg("ownerId change failed for function %u, because it is a builtin function.", procOid))); | ||
| 2587 | + } | ||
| 2588 | + | ||
| 2589 | + if (!(superuser_arg(GetUserId())) && isSecdef && !enablePrivilegesSeparate || | ||
| 2590 | + (enablePrivilegesSeparate && isSecdef)) { | ||
| 2591 | + ereport(ERROR, | ||
| 2592 | + (errmodule(MOD_PLSQL), errcode(ERRCODE_SYNTAX_ERROR), | ||
| 2593 | + errmsg("security definer function not allow alter owner"), | ||
| 2594 | + errdetail("please delete function and rebuild function"), | ||
| 2595 | + errcause("for security, not allow alter security definer function owner"), | ||
| 2596 | + erraction("delete and rebuild function"))); | ||
| 2597 | + } | ||
| 2598 | + | ||
| 2599 | + if (superuser_arg(GetUserId()) && isOperatoradmin(newOwnerId) && isSecdef) { | ||
| 2600 | + ereport(ERROR, | ||
| 2601 | + (errmodule(MOD_PLSQL), errcode(ERRCODE_SYNTAX_ERROR), | ||
| 2602 | + errmsg("sysadmin can not alter security definer function owner to opradmin"), | ||
| 2603 | + errdetail("please delete function and rebuild function"), | ||
| 2604 | + errcause("for security, not allow alter security definer function owner to opradmin"), | ||
| 2605 | + erraction("delete and rebuild function"))); | ||
| 2606 | + } | ||
| 2607 | +} | ||
| 2608 | + | ||
| 2576 | /* | 2609 | /* |
| 2577 | * @Description: Alter function owner. | 2610 | * @Description: Alter function owner. |
| 2578 | * @in rel: pg_proc relation. | 2611 | * @in rel: pg_proc relation. |
| @@ -2591,12 +2624,7 @@ static void AlterFunctionOwner_internal(Relation rel, HeapTuple tup, Oid newOwne | |||
| 2591 | 2624 | ||
| 2592 | procForm = (Form_pg_proc)GETSTRUCT(tup); | 2625 | procForm = (Form_pg_proc)GETSTRUCT(tup); |
| 2593 | procOid = HeapTupleGetOid(tup); | 2626 | procOid = HeapTupleGetOid(tup); |
| 2594 | - | 2627 | + CheckAlterFunctionPrivileges(newOwnerId, procOid, procForm->prosecdef); |
| 2595 | - if (IsSystemObjOid(procOid) && u_sess->attr.attr_common.IsInplaceUpgrade == false) { | ||
| 2596 | - ereport(ERROR, | ||
| 2597 | - (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), | ||
| 2598 | - errmsg("ownerId change failed for function %u, because it is a builtin function.", procOid))); | ||
| 2599 | - } | ||
| 2600 | 2628 | ||
| 2601 | /* | 2629 | /* |
| 2602 | * If the new owner is the same as the existing owner, consider the | 2630 | * If the new owner is the same as the existing owner, consider the |
| @@ -4113,16 +4141,6 @@ static void checkAllowAlter(HeapTuple tup) { | |||
| 4113 | errcause("package is one object,not allow alter function in package"), | 4141 | errcause("package is one object,not allow alter function in package"), |
| 4114 | erraction("rebuild package"))); | 4142 | erraction("rebuild package"))); |
| 4115 | } | 4143 | } |
| 4116 | - prosecdef_datum = SysCacheGetAttr(PROCOID, tup, Anum_pg_proc_prosecdef, &isnull); | ||
| 4117 | - prosecdef = DatumGetBool(prosecdef_datum); | ||
| 4118 | - if (prosecdef) { | ||
| 4119 | - ereport(ERROR, | ||
| 4120 | - (errmodule(MOD_PLSQL), errcode(ERRCODE_SYNTAX_ERROR), | ||
| 4121 | - errmsg("security definer function not allow alter owner"), | ||
| 4122 | - errdetail("please delete function and rebuild function"), | ||
| 4123 | - errcause("for security, not allow alter security definer function owner"), | ||
| 4124 | - erraction("delete and rebuild function"))); | ||
| 4125 | - } | ||
| 4126 | } | 4144 | } |
| 4127 | 4145 | ||
| 4128 | /* | 4146 | /* |
| @@ -4174,48 +4192,77 @@ Const* processOutResToConst(char* value, Oid atttypid) | |||
| 4174 | } | 4192 | } |
| 4175 | return con; | 4193 | return con; |
| 4176 | } | 4194 | } |
| 4195 | +#endif | ||
| 4177 | 4196 | ||
| 4178 | /* | 4197 | /* |
| 4179 | - * Execute call procedure statememt here | 4198 | + * Execute CALL statement |
| 4199 | + * | ||
| 4200 | + * Inside a top-level CALL statement, transaction-terminating commands such as | ||
| 4201 | + * COMMIT or a PL-specific equivalent are allowed. The terminology in the SQL | ||
| 4202 | + * standard is that CALL establishes a non-atomic execution context. Most | ||
| 4203 | + * other commands establish an atomic execution context, in which transaction | ||
| 4204 | + * control actions are not allowed. If there are nested executions of CALL, | ||
| 4205 | + * we want to track the execution context recursively, so that the nested | ||
| 4206 | + * CALLs can also do transaction control. Note, however, that for example in | ||
| 4207 | + * CALL -> SELECT -> CALL, the second call cannot do transaction control, | ||
| 4208 | + * because the SELECT in between establishes an atomic execution context. | ||
| 4209 | + * | ||
| 4210 | + * So when ExecuteCallStmt() is called from the top level, we pass in atomic = | ||
| 4211 | + * false (recall that that means transactions = yes). We then create a | ||
| 4212 | + * CallContext node with content atomic = false, which is passed in the | ||
| 4213 | + * fcinfo->context field to the procedure invocation. The language | ||
| 4214 | + * implementation should then take appropriate measures to allow or prevent | ||
| 4215 | + * transaction commands based on that information, e.g., call | ||
| 4216 | + * SPI_connect_ext(SPI_OPT_NONATOMIC). The language should also pass on the | ||
| 4217 | + * atomic flag to any nested invocations to CALL. | ||
| 4218 | + * | ||
| 4219 | + * The expression data structures and execution context that we create | ||
| 4220 | + * within this function are children of the portalContext of the Portal | ||
| 4221 | + * that the CALL utility statement runs in. Therefore, any pass-by-ref | ||
| 4222 | + * values that we're passing to the procedure will survive transaction | ||
| 4223 | + * commits that might occur inside the procedure. | ||
| 4180 | */ | 4224 | */ |
| 4181 | -void ExecuteCallStmt(DolphinCallStmt *stmt, ParamListInfo params, bool atomic) | 4225 | +void ExecuteCallStmt(DolphinCallStmt *stmt, ParamListInfo params, bool atomic, DestReceiver *dest) |
| 4182 | { | 4226 | { |
| 4183 | ListCell *lc; | 4227 | ListCell *lc; |
| 4184 | FuncExpr *fexpr; | 4228 | FuncExpr *fexpr; |
| 4185 | - int nargs; | ||
| 4186 | - int i; | ||
| 4187 | AclResult aclresult; | 4229 | AclResult aclresult; |
| 4188 | FmgrInfo flinfo; | 4230 | FmgrInfo flinfo; |
| 4189 | CallContext *callcontext; | 4231 | CallContext *callcontext; |
| 4190 | - EState *estate; | 4232 | + EState *estate; |
| 4191 | ExprContext *econtext; | 4233 | ExprContext *econtext; |
| 4192 | HeapTuple tp; | 4234 | HeapTuple tp; |
| 4235 | + FunctionCallInfoData fcinfo; | ||
| 4193 | PgStat_FunctionCallUsage fcusage; | 4236 | PgStat_FunctionCallUsage fcusage; |
| 4194 | Datum retval; | 4237 | Datum retval; |
| 4195 | - FunctionCallInfoData fcinfo; | 4238 | + int nargs = 0; |
| 4239 | + int i = 0; | ||
| 4196 | fexpr = stmt->funcexpr; | 4240 | fexpr = stmt->funcexpr; |
| 4197 | Assert(fexpr); | 4241 | Assert(fexpr); |
| 4198 | Assert(IsA(fexpr, FuncExpr)); | 4242 | Assert(IsA(fexpr, FuncExpr)); |
| 4199 | 4243 | ||
| 4200 | Oid definer = GetUserId(); | 4244 | Oid definer = GetUserId(); |
| 4201 | - Form_pg_proc procStruct; | ||
| 4202 | - volatile bool topCall = false; /* use volatile to let PG_CATCH get the right value */ | ||
| 4203 | - /* Get function's pg_proc entry */ | ||
| 4204 | tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(fexpr->funcid)); | 4245 | tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(fexpr->funcid)); |
| 4205 | if (!HeapTupleIsValid(tp)) { | 4246 | if (!HeapTupleIsValid(tp)) { |
| 4206 | ereport(ERROR, (errcode(ERRCODE_CACHE_LOOKUP_FAILED), | 4247 | ereport(ERROR, (errcode(ERRCODE_CACHE_LOOKUP_FAILED), |
| 4207 | errmsg("cache lookup failed for function %u", fexpr->funcid))); | 4248 | errmsg("cache lookup failed for function %u", fexpr->funcid))); |
| 4208 | } | 4249 | } |
| 4250 | +#ifdef DOLPHIN | ||
| 4251 | + Form_pg_proc procStruct; | ||
| 4252 | + volatile bool topCall = false; /* use volatile to let PG_CATCH get the right value */ | ||
| 4253 | + /* Get function's pg_proc entry */ | ||
| 4209 | procStruct = (Form_pg_proc)GETSTRUCT(tp); | 4254 | procStruct = (Form_pg_proc)GETSTRUCT(tp); |
| 4210 | /* in b format database , we shoule check definer operation */ | 4255 | /* in b format database , we shoule check definer operation */ |
| 4211 | if (procStruct->prosecdef) { | 4256 | if (procStruct->prosecdef) { |
| 4212 | definer = procStruct->proowner; | 4257 | definer = procStruct->proowner; |
| 4213 | } | 4258 | } |
| 4259 | +#endif | ||
| 4214 | 4260 | ||
| 4215 | aclresult = pg_proc_aclcheck(fexpr->funcid, definer, ACL_EXECUTE); | 4261 | aclresult = pg_proc_aclcheck(fexpr->funcid, definer, ACL_EXECUTE); |
| 4216 | if (aclresult != ACLCHECK_OK) | 4262 | if (aclresult != ACLCHECK_OK) |
| 4217 | aclcheck_error(aclresult, ACL_KIND_PROC, get_func_name(fexpr->funcid)); | 4263 | aclcheck_error(aclresult, ACL_KIND_PROC, get_func_name(fexpr->funcid)); |
| 4218 | 4264 | ||
| 4265 | +#ifdef DOLPHIN | ||
| 4219 | /* ensure it is a procedure and language is plogsql */ | 4266 | /* ensure it is a procedure and language is plogsql */ |
| 4220 | char prokind = get_func_prokind(fexpr->funcid); | 4267 | char prokind = get_func_prokind(fexpr->funcid); |
| 4221 | if (!PROC_IS_PRO(prokind)) { | 4268 | if (!PROC_IS_PRO(prokind)) { |
| @@ -4233,68 +4280,89 @@ void ExecuteCallStmt(DolphinCallStmt *stmt, ParamListInfo params, bool atomic) | |||
| 4233 | /* let memcontext to free old args */ | 4280 | /* let memcontext to free old args */ |
| 4234 | fexpr->args = dolphin_add_function_defaults(fexpr->args, tp); | 4281 | fexpr->args = dolphin_add_function_defaults(fexpr->args, tp); |
| 4235 | } | 4282 | } |
| 4283 | +#endif | ||
| 4236 | /* Prep the context object we'll pass to the procedure */ | 4284 | /* Prep the context object we'll pass to the procedure */ |
| 4237 | callcontext = makeNode(CallContext); | 4285 | callcontext = makeNode(CallContext); |
| 4238 | callcontext->atomic = atomic; | 4286 | callcontext->atomic = atomic; |
| 4239 | 4287 | ||
| 4288 | + /* | ||
| 4289 | + * If proconfig is set we can't allow transaction commands because of the | ||
| 4290 | + * way the GUC stacking works: The transaction boundary would have to pop | ||
| 4291 | + * the proconfig setting off the stack. That restriction could be lifted | ||
| 4292 | + * by redesigning the GUC nesting mechanism a bit. | ||
| 4293 | + */ | ||
| 4240 | if (!heap_attisnull(tp, Anum_pg_proc_proconfig, NULL)) | 4294 | if (!heap_attisnull(tp, Anum_pg_proc_proconfig, NULL)) |
| 4241 | callcontext->atomic = true; | 4295 | callcontext->atomic = true; |
| 4242 | 4296 | ||
| 4297 | + /* | ||
| 4298 | + * In security definer procedures, we can't allow transaction commands. | ||
| 4299 | + * StartTransaction() insists that the security context stack is empty, | ||
| 4300 | + * and AbortTransaction() resets the security context. This could be | ||
| 4301 | + * reorganized, but right now it doesn't work. | ||
| 4302 | + */ | ||
| 4303 | + if (((Form_pg_proc) GETSTRUCT(tp))->prosecdef) | ||
| 4304 | + callcontext->atomic = true; | ||
| 4305 | + | ||
| 4243 | ReleaseSysCache(tp); | 4306 | ReleaseSysCache(tp); |
| 4244 | 4307 | ||
| 4245 | /* safety check; see ExecInitFunc() */ | 4308 | /* safety check; see ExecInitFunc() */ |
| 4246 | nargs = list_length(fexpr->args); | 4309 | nargs = list_length(fexpr->args); |
| 4247 | if (nargs > FUNC_MAX_ARGS) | 4310 | if (nargs > FUNC_MAX_ARGS) |
| 4248 | - ereport(ERROR, (errcode(ERRCODE_TOO_MANY_ARGUMENTS), | 4311 | + ereport(ERROR, |
| 4249 | - errmsg_plural("cannot pass more than %d argument to a procedure", | 4312 | + (errcode(ERRCODE_TOO_MANY_ARGUMENTS), |
| 4250 | - "cannot pass more than %d arguments to a procedure", | 4313 | + errmsg_plural("cannot pass more than %d argument to a procedure", |
| 4251 | - FUNC_MAX_ARGS, | 4314 | + "cannot pass more than %d arguments to a procedure", |
| 4252 | - FUNC_MAX_ARGS))); | 4315 | + FUNC_MAX_ARGS, |
| 4316 | + FUNC_MAX_ARGS))); | ||
| 4253 | 4317 | ||
| 4254 | /* Initialize function call structure */ | 4318 | /* Initialize function call structure */ |
| 4319 | + InvokeFunctionExecuteHook(fexpr->funcid); | ||
| 4255 | fmgr_info(fexpr->funcid, &flinfo); | 4320 | fmgr_info(fexpr->funcid, &flinfo); |
| 4256 | fmgr_info_set_expr((Node *) fexpr, &flinfo); | 4321 | fmgr_info_set_expr((Node *) fexpr, &flinfo); |
| 4257 | InitFunctionCallInfoData(fcinfo, &flinfo, nargs, fexpr->inputcollid, | 4322 | InitFunctionCallInfoData(fcinfo, &flinfo, nargs, fexpr->inputcollid, |
| 4258 | - (Node *) callcontext, NULL); | 4323 | + (Node *) callcontext, NULL); |
| 4259 | 4324 | ||
| 4260 | /* | 4325 | /* |
| 4261 | - * Evaluate procedure arguments inside a suitable execution context. Note | 4326 | + * Evaluate procedure arguments inside a suitable execution context. Note |
| 4262 | - * we can't free this context till the procedure returns. | 4327 | + * we can't free this context till the procedure returns. |
| 4263 | - */ | 4328 | + */ |
| 4264 | estate = CreateExecutorState(); | 4329 | estate = CreateExecutorState(); |
| 4265 | estate->es_param_list_info = params; | 4330 | estate->es_param_list_info = params; |
| 4266 | econtext = CreateExprContext(estate); | 4331 | econtext = CreateExprContext(estate); |
| 4267 | 4332 | ||
| 4268 | /* | 4333 | /* |
| 4269 | - * If we're called in non-atomic context, we also have to ensure that the | 4334 | + * If we're called in non-atomic context, we also have to ensure that the |
| 4270 | - * argument expressions run with an up-to-date snapshot. Our caller will | 4335 | + * argument expressions run with an up-to-date snapshot. Our caller will |
| 4271 | - * have provided a current snapshot in atomic contexts, but not in | 4336 | + * have provided a current snapshot in atomic contexts, but not in |
| 4272 | - * non-atomic contexts, because the possibility of a COMMIT/ROLLBACK | 4337 | + * non-atomic contexts, because the possibility of a COMMIT/ROLLBACK |
| 4273 | - * destroying the snapshot makes higher-level management too complicated. | 4338 | + * destroying the snapshot makes higher-level management too complicated. |
| 4274 | - */ | 4339 | + */ |
| 4275 | - if (!atomic) | 4340 | + if (!atomic) { |
| 4276 | PushActiveSnapshot(GetTransactionSnapshot()); | 4341 | PushActiveSnapshot(GetTransactionSnapshot()); |
| 4342 | + } | ||
| 4277 | 4343 | ||
| 4278 | - i = 0; | 4344 | + foreach(lc, fexpr->args) { |
| 4279 | - foreach(lc, fexpr->args) | ||
| 4280 | - { | ||
| 4281 | ExprState *exprstate; | 4345 | ExprState *exprstate; |
| 4282 | Datum val; | 4346 | Datum val; |
| 4283 | bool isnull; | 4347 | bool isnull; |
| 4284 | - exprstate = ExecPrepareExpr((Expr*)lfirst(lc), estate); | 4348 | + |
| 4285 | - val = ExecEvalExprSwitchContext(exprstate, econtext, &isnull, NULL); | 4349 | + exprstate = ExecPrepareExpr((Expr *)lfirst(lc), estate); |
| 4350 | + val = ExecEvalExprSwitchContext(exprstate, econtext, &isnull); | ||
| 4286 | 4351 | ||
| 4287 | fcinfo.arg[i] = val; | 4352 | fcinfo.arg[i] = val; |
| 4288 | fcinfo.argnull[i] = isnull; | 4353 | fcinfo.argnull[i] = isnull; |
| 4354 | + | ||
| 4289 | i++; | 4355 | i++; |
| 4290 | } | 4356 | } |
| 4291 | 4357 | ||
| 4292 | /* Get rid of temporary snapshot for arguments, if we made one */ | 4358 | /* Get rid of temporary snapshot for arguments, if we made one */ |
| 4293 | - if (!atomic) | 4359 | + if (!atomic) { |
| 4294 | PopActiveSnapshot(); | 4360 | PopActiveSnapshot(); |
| 4361 | + } | ||
| 4295 | 4362 | ||
| 4296 | /* Here we actually call the procedure */ | 4363 | /* Here we actually call the procedure */ |
| 4297 | pgstat_init_function_usage(&fcinfo, &fcusage); | 4364 | pgstat_init_function_usage(&fcinfo, &fcusage); |
| 4365 | +#ifdef DOLPHIN | ||
| 4298 | PG_TRY(); | 4366 | PG_TRY(); |
| 4299 | { | 4367 | { |
| 4300 | if (!GetSessionContext()->is_dolphin_call_stmt) | 4368 | if (!GetSessionContext()->is_dolphin_call_stmt) |
| @@ -4311,61 +4379,74 @@ void ExecuteCallStmt(DolphinCallStmt *stmt, ParamListInfo params, bool atomic) | |||
| 4311 | PG_END_TRY(); | 4379 | PG_END_TRY(); |
| 4312 | if (topCall) | 4380 | if (topCall) |
| 4313 | GetSessionContext()->is_dolphin_call_stmt = false; | 4381 | GetSessionContext()->is_dolphin_call_stmt = false; |
| 4382 | +#else | ||
| 4383 | + retval = FunctionCallInvoke(&fcinfo); | ||
| 4384 | +#endif | ||
| 4385 | + | ||
| 4314 | pgstat_end_function_usage(&fcusage, true); | 4386 | pgstat_end_function_usage(&fcusage, true); |
| 4315 | 4387 | ||
| 4316 | /* Handle the procedure's outputs */ | 4388 | /* Handle the procedure's outputs */ |
| 4317 | if (fexpr->funcresulttype == RECORDOID) { | 4389 | if (fexpr->funcresulttype == RECORDOID) { |
| 4318 | - /* send tuple to UserVar */ | 4390 | + /* send tuple to UserVar or client */ |
| 4391 | + Oid tupType; | ||
| 4392 | + int32 tupTypmod; | ||
| 4393 | + TupleDesc retdesc; | ||
| 4394 | + HeapTupleData rettupdata; | ||
| 4395 | + TupOutputState *tstate; | ||
| 4396 | + TupleTableSlot *slot; | ||
| 4319 | HeapTupleHeader td; | 4397 | HeapTupleHeader td; |
| 4320 | - Oid tupType; | ||
| 4321 | - int32 tupTypmod; | ||
| 4322 | - TupleDesc retdesc; | ||
| 4323 | - HeapTupleData rettupdata; | ||
| 4324 | - TupleTableSlot *slot; | ||
| 4325 | 4398 | ||
| 4326 | - if (fcinfo.isnull) | 4399 | + if (fcinfo.isnull) { |
| 4327 | - ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), | 4400 | + elog(ERROR, "procedure returned null record"); |
| 4328 | - errmsg("procedure out parameters shoule be saved"))); | 4401 | + } |
| 4329 | - | ||
| 4330 | - /* make a tupletableslot and save uservar here */ | ||
| 4331 | td = DatumGetHeapTupleHeader(retval); | 4402 | td = DatumGetHeapTupleHeader(retval); |
| 4332 | tupType = HeapTupleHeaderGetTypeId(td); | 4403 | tupType = HeapTupleHeaderGetTypeId(td); |
| 4333 | tupTypmod = HeapTupleHeaderGetTypMod(td); | 4404 | tupTypmod = HeapTupleHeaderGetTypMod(td); |
| 4334 | retdesc = lookup_rowtype_tupdesc(tupType, tupTypmod); | 4405 | retdesc = lookup_rowtype_tupdesc(tupType, tupTypmod); |
| 4335 | - slot = MakeSingleTupleTableSlot(retdesc); | ||
| 4336 | 4406 | ||
| 4337 | rettupdata.t_len = HeapTupleHeaderGetDatumLength(td); | 4407 | rettupdata.t_len = HeapTupleHeaderGetDatumLength(td); |
| 4338 | ItemPointerSetInvalid(&(rettupdata.t_self)); | 4408 | ItemPointerSetInvalid(&(rettupdata.t_self)); |
| 4339 | rettupdata.t_tableOid = InvalidOid; | 4409 | rettupdata.t_tableOid = InvalidOid; |
| 4340 | rettupdata.t_data = td; | 4410 | rettupdata.t_data = td; |
| 4341 | 4411 | ||
| 4342 | - slot = ExecStoreTuple(&rettupdata, slot, InvalidBuffer, false); | 4412 | + if (stmt->outargs == NIL) { |
| 4343 | - tableam_tslot_getallattrs(slot); | 4413 | + tstate = begin_tup_output_tupdesc(dest, retdesc); |
| 4344 | - uint i = 0; | 4414 | + |
| 4345 | - ListCell* lc; | 4415 | + slot = ExecStoreTuple(&rettupdata, tstate->slot, InvalidBuffer, false); |
| 4346 | - /* set uservar value */ | 4416 | + tstate->dest->receiveSlot(slot, tstate->dest); |
| 4347 | - foreach (lc, stmt->outargs) { | 4417 | + |
| 4348 | - Oid out_func_oid = InvalidOid; | 4418 | + end_tup_output(tstate); |
| 4349 | - bool isvarlena = false; | 4419 | + } else { |
| 4350 | - FmgrInfo* finfo = (FmgrInfo*)palloc(1 * sizeof(FmgrInfo)); | 4420 | + slot = MakeSingleTupleTableSlot(retdesc); |
| 4351 | - Oid atttypid = ((UserVar*)lfirst(lc))->value ? ((Const*)((UserVar*)lfirst(lc))->value)->consttype : | 4421 | + |
| 4352 | - slot->tts_tupleDescriptor->attrs[i].atttypid; | 4422 | + slot = ExecStoreTuple(&rettupdata, slot, InvalidBuffer, false); |
| 4353 | - getTypeOutputInfo(atttypid, &out_func_oid, &isvarlena); | 4423 | + tableam_tslot_getallattrs(slot); |
| 4354 | - fmgr_info(out_func_oid, finfo); | 4424 | + uint i = 0; |
| 4355 | - if (slot->tts_values[i] != 0) { | 4425 | + ListCell* lc; |
| 4356 | - char* ovalue = OutputFunctionCall(finfo, slot->tts_values[i]); | 4426 | + /* set uservar value */ |
| 4357 | - Const *con = processOutResToConst(ovalue, atttypid); | 4427 | + foreach (lc, stmt->outargs) { |
| 4358 | - Node* rnode = atttypid == BOOLOID ? (Node*)con : type_transfer((Node*)con, atttypid, true); | 4428 | + Oid out_func_oid = InvalidOid; |
| 4359 | - Expr *var_expr = (Expr *)const_expression_to_const(rnode); | 4429 | + bool isvarlena = false; |
| 4360 | - check_variable_value_info(((UserVar *)lfirst(lc))->name, var_expr); | 4430 | + FmgrInfo* finfo = (FmgrInfo*)palloc(1 * sizeof(FmgrInfo)); |
| 4361 | - pfree(ovalue); | 4431 | + Oid atttypid = ((UserVar*)lfirst(lc))->value ? ((Const*)((UserVar*)lfirst(lc))->value)->consttype : |
| 4432 | + slot->tts_tupleDescriptor->attrs[i].atttypid; | ||
| 4433 | + getTypeOutputInfo(atttypid, &out_func_oid, &isvarlena); | ||
| 4434 | + fmgr_info(out_func_oid, finfo); | ||
| 4435 | + if (slot->tts_values[i] != 0) { | ||
| 4436 | + char* ovalue = OutputFunctionCall(finfo, slot->tts_values[i]); | ||
| 4437 | + Const *con = processOutResToConst(ovalue, atttypid); | ||
| 4438 | + Node* rnode = atttypid == BOOLOID ? (Node*)con : type_transfer((Node*)con, atttypid, true); | ||
| 4439 | + Expr *var_expr = (Expr *)const_expression_to_const(rnode); | ||
| 4440 | + check_variable_value_info(((UserVar *)lfirst(lc))->name, var_expr); | ||
| 4441 | + pfree(ovalue); | ||
| 4442 | + } | ||
| 4443 | + pfree(finfo); | ||
| 4444 | + ++i; | ||
| 4362 | } | 4445 | } |
| 4363 | - pfree(finfo); | 4446 | + ExecDropSingleTupleTableSlot(slot); |
| 4364 | - ++i; | ||
| 4365 | } | 4447 | } |
| 4366 | - ExecDropSingleTupleTableSlot(slot); | ||
| 4367 | ReleaseTupleDesc(retdesc); | 4448 | ReleaseTupleDesc(retdesc); |
| 4368 | - } else if (fexpr->funcresulttype != VOIDOID) { | 4449 | + } else if (stmt->outargs != NIL && fexpr->funcresulttype != VOIDOID) { |
| 4369 | Assert(list_length(stmt->outargs) == 1); | 4450 | Assert(list_length(stmt->outargs) == 1); |
| 4370 | Oid out_func_oid = InvalidOid; | 4451 | Oid out_func_oid = InvalidOid; |
| 4371 | bool isvarlena = false; | 4452 | bool isvarlena = false; |
| @@ -4386,4 +4467,3 @@ void ExecuteCallStmt(DolphinCallStmt *stmt, ParamListInfo params, bool atomic) | |||
| 4386 | } | 4467 | } |
| 4387 | FreeExecutorState(estate); | 4468 | FreeExecutorState(estate); |
| 4388 | } | 4469 | } |
| 4389 | -#endif | ||
| @@ -32,6 +32,8 @@ | |||
| 32 | #include "parser/parse_collate.h" | 32 | #include "parser/parse_collate.h" |
| 33 | #include "parser/parse_expr.h" | 33 | #include "parser/parse_expr.h" |
| 34 | #include "parser/parse_type.h" | 34 | #include "parser/parse_type.h" |
| 35 | +#include "parser/parse_func.h" | ||
| 36 | +#include "funcapi.h" | ||
| 35 | #include "pgstat.h" | 37 | #include "pgstat.h" |
| 36 | #include "rewrite/rewriteHandler.h" | 38 | #include "rewrite/rewriteHandler.h" |
| 37 | #include "tcop/pquery.h" | 39 | #include "tcop/pquery.h" |
| @@ -62,6 +64,16 @@ void InitQueryHashTable(void); | |||
| 62 | static ParamListInfo EvaluateParams(CachedPlanSource* psrc, List* params, const char* queryString, EState* estate); | 64 | static ParamListInfo EvaluateParams(CachedPlanSource* psrc, List* params, const char* queryString, EState* estate); |
| 63 | static Datum build_regtype_array(const Oid* param_types, int num_params); | 65 | static Datum build_regtype_array(const Oid* param_types, int num_params); |
| 64 | 66 | ||
| 67 | +SPIPlanPtr prepare_stmt_exec(PLpgSQL_execstate *estate, PLpgSQL_function *func, | ||
| 68 | + PLpgSQL_stmt_exec *stmt, bool keepplan = false); | ||
| 69 | +static void prepare_select_plan_for_scalar_func(PLpgSQL_execstate *estate, PLpgSQL_expr *expr, | ||
| 70 | + int firstArgLocation, const char *newParams); | ||
| 71 | +static bool IsExecStmtOnScalarFunc(const char *stmt, int *firstArgLocation, const char **newParams); | ||
| 72 | +static char *rewrite_exec_scalar_func_params(const char *stmt, List *raw_parsetree_list, int firstArgLocation); | ||
| 73 | +static List *get_func_info_from_raw_parsetree(List *raw_parsetree_list, int *nargs, | ||
| 74 | + bool *funcVariadic, int *firstArgLocation); | ||
| 75 | + | ||
| 76 | + | ||
| 65 | extern void destroy_handles(); | 77 | extern void destroy_handles(); |
| 66 | 78 | ||
| 67 | static void CopyPlanForGPCIfNecessary(CachedPlanSource* psrc, Portal portal) | 79 | static void CopyPlanForGPCIfNecessary(CachedPlanSource* psrc, Portal portal) |
| @@ -2534,3 +2546,239 @@ bool quickPlanner(List* querytree_list, Node* parsetree, const char*queryString, | |||
| 2534 | FreeExecutorState(estate); | 2546 | FreeExecutorState(estate); |
| 2535 | return true; | 2547 | return true; |
| 2536 | } | 2548 | } |
| 2549 | + | ||
| 2550 | +SPIPlanPtr prepare_stmt_exec(PLpgSQL_execstate *estate, PLpgSQL_function *func, PLpgSQL_stmt_exec *stmt, bool keepplan) | ||
| 2551 | +{ | ||
| 2552 | + int firstArgLocation; | ||
| 2553 | + const char *newParams = NULL; | ||
| 2554 | + PLpgSQL_expr *expr = stmt->expr; | ||
| 2555 | + bool isStmtScalarFunc; | ||
| 2556 | + | ||
| 2557 | + /* Do the query in local context to free memory at earliest */ | ||
| 2558 | + MemoryContext oldcontext = MemoryContextSwitchTo(estate->eval_econtext->ecxt_per_tuple_memory); | ||
| 2559 | + | ||
| 2560 | + isStmtScalarFunc = IsExecStmtOnScalarFunc(expr->query, &firstArgLocation, &newParams); | ||
| 2561 | + MemoryContextSwitchTo(oldcontext); | ||
| 2562 | + | ||
| 2563 | + if (isStmtScalarFunc) { | ||
| 2564 | + prepare_select_plan_for_scalar_func(estate, expr, firstArgLocation, newParams); | ||
| 2565 | + } else { | ||
| 2566 | + /* | ||
| 2567 | + * Don't save the plan if not in atomic context. Otherwise, | ||
| 2568 | + * transaction ends would cause errors about plancache leaks. | ||
| 2569 | + * | ||
| 2570 | + * XXX This would be fixable with some plancache/resowner surgery | ||
| 2571 | + * elsewhere, but for now we'll just work around this here. | ||
| 2572 | + */ | ||
| 2573 | + exec_prepare_plan_interface(estate, expr, 0); | ||
| 2574 | + } | ||
| 2575 | + | ||
| 2576 | + /* | ||
| 2577 | + * Force target to be recalculated whenever the plan changes, in case the | ||
| 2578 | + * procedure's argument list has changed. | ||
| 2579 | + */ | ||
| 2580 | + stmt->target = NULL; | ||
| 2581 | + | ||
| 2582 | + return expr->plan; | ||
| 2583 | +} | ||
| 2584 | + | ||
| 2585 | +static bool IsExecStmtOnScalarFunc(const char *stmt, int *firstArgLocation, const char **newParams) | ||
| 2586 | +{ | ||
| 2587 | + List *raw_parsetree_list; | ||
| 2588 | + List *funcname; | ||
| 2589 | + int nargs; | ||
| 2590 | + bool funcVariadic; | ||
| 2591 | + Oid arg_types[FUNC_MAX_ARGS]; | ||
| 2592 | + FuncDetailCode fdresult; | ||
| 2593 | + Oid funcid; | ||
| 2594 | + Oid rettype; | ||
| 2595 | + bool retset; | ||
| 2596 | + int nvargs; | ||
| 2597 | + Oid vatype; | ||
| 2598 | + Oid *typeids; | ||
| 2599 | + int i; | ||
| 2600 | + | ||
| 2601 | + /* | ||
| 2602 | + * Stmt should be syntactically vaild since it was verified during | ||
| 2603 | + * compiliation | ||
| 2604 | + */ | ||
| 2605 | + raw_parsetree_list = pg_parse_query(stmt, NULL, GetRawParser()); | ||
| 2606 | + funcname = get_func_info_from_raw_parsetree(raw_parsetree_list, | ||
| 2607 | + &nargs, &funcVariadic, | ||
| 2608 | + firstArgLocation); | ||
| 2609 | + if (!funcname) { | ||
| 2610 | + return false; | ||
| 2611 | + } | ||
| 2612 | + /* safety check */ | ||
| 2613 | + if (nargs > FUNC_MAX_ARGS) | ||
| 2614 | + ereport(ERROR, (errcode(ERRCODE_TOO_MANY_ARGUMENTS), | ||
| 2615 | + errmsg("cannot pass more than %d arguments to a procedure", | ||
| 2616 | + FUNC_MAX_ARGS))); | ||
| 2617 | + | ||
| 2618 | + for (i = 0; i < nargs; ++i) { | ||
| 2619 | + /* We really don't care of the exact argument datatypes */ | ||
| 2620 | + arg_types[i] = UNKNOWNOID; | ||
| 2621 | + } | ||
| 2622 | + | ||
| 2623 | + fdresult = func_get_detail(funcname, | ||
| 2624 | + NIL, NIL, | ||
| 2625 | + nargs, arg_types, | ||
| 2626 | + funcVariadic, true, | ||
| 2627 | + &funcid, &rettype, &retset, | ||
| 2628 | + &nvargs, &vatype, | ||
| 2629 | + &typeids, NULL); | ||
| 2630 | + if (fdresult != FUNCDETAIL_NORMAL) { | ||
| 2631 | + return false; | ||
| 2632 | + } | ||
| 2633 | + if (get_func_result_type(funcid, NULL, NULL) != TYPEFUNC_SCALAR) { | ||
| 2634 | + return false; | ||
| 2635 | + } | ||
| 2636 | + | ||
| 2637 | + if (nargs > 0) { | ||
| 2638 | + *newParams = rewrite_exec_scalar_func_params(stmt, raw_parsetree_list, *firstArgLocation); | ||
| 2639 | + } | ||
| 2640 | + | ||
| 2641 | + return true; | ||
| 2642 | +} | ||
| 2643 | + | ||
| 2644 | +static List *get_func_info_from_raw_parsetree(List *raw_parsetree_list, | ||
| 2645 | + int *nargs, bool *funcVariadic, | ||
| 2646 | + int *firstArgLocation) | ||
| 2647 | +{ | ||
| 2648 | + DolphinCallStmt *cstmt; | ||
| 2649 | + FuncCall *funccall; | ||
| 2650 | + | ||
| 2651 | + if (!raw_parsetree_list) { | ||
| 2652 | + return NIL; | ||
| 2653 | + } | ||
| 2654 | + if (list_length(raw_parsetree_list) != 1) { | ||
| 2655 | + return NIL; | ||
| 2656 | + } | ||
| 2657 | + | ||
| 2658 | + cstmt = (DolphinCallStmt *) linitial(raw_parsetree_list); | ||
| 2659 | + if (!cstmt || !cstmt->funccall) { | ||
| 2660 | + return NIL; | ||
| 2661 | + } | ||
| 2662 | + | ||
| 2663 | + funccall = cstmt->funccall; | ||
| 2664 | + | ||
| 2665 | + if (nargs) { | ||
| 2666 | + *nargs = list_length(funccall->args); | ||
| 2667 | + } | ||
| 2668 | + if (funcVariadic) { | ||
| 2669 | + *funcVariadic = funccall->func_variadic; | ||
| 2670 | + } | ||
| 2671 | + | ||
| 2672 | + Assert(firstArgLocation != NULL); | ||
| 2673 | + if (*nargs > 0) { | ||
| 2674 | + *firstArgLocation = exprLocation((Node *) linitial(funccall->args)); | ||
| 2675 | + } else { | ||
| 2676 | + *firstArgLocation = -1; | ||
| 2677 | + } | ||
| 2678 | + | ||
| 2679 | + return funccall->funcname; | ||
| 2680 | +} | ||
| 2681 | + | ||
| 2682 | +/* | ||
| 2683 | + * When dealing with EXEC on scalar function, we will later rewrite it to a | ||
| 2684 | + * SELECT on the scalar function before passing to the main parser. There are | ||
| 2685 | + * differences in syntax when passing arguments between EXEC and SELECT. For | ||
| 2686 | + * example, EXEC allows "<param1> = <value1>, <param2> = <value2>", whereas | ||
| 2687 | + * SELECT only allows ":=" or "=>" for such. | ||
| 2688 | + * | ||
| 2689 | + * This function returns the rewritten parameters portion of the stmt, or | ||
| 2690 | + * NULL if no rewriting is necessary. | ||
| 2691 | + */ | ||
| 2692 | +static char *rewrite_exec_scalar_func_params(const char *stmt, List *raw_parsetree_list, int firstArgLocation) | ||
| 2693 | +{ | ||
| 2694 | + ListCell *lc; | ||
| 2695 | + DolphinCallStmt *cstmt; | ||
| 2696 | + FuncCall *funccall; | ||
| 2697 | + StringInfoData dest; | ||
| 2698 | + int prev = firstArgLocation; | ||
| 2699 | + | ||
| 2700 | + if (firstArgLocation == -1) | ||
| 2701 | + return NULL; | ||
| 2702 | + | ||
| 2703 | + cstmt = (DolphinCallStmt *) linitial(raw_parsetree_list); | ||
| 2704 | + if (!cstmt || !cstmt->funccall) | ||
| 2705 | + return NULL; | ||
| 2706 | + | ||
| 2707 | + initStringInfo(&dest); | ||
| 2708 | + funccall = cstmt->funccall; | ||
| 2709 | + foreach(lc, funccall->args) { | ||
| 2710 | + Node *expr = (Node *)lfirst(lc); | ||
| 2711 | + | ||
| 2712 | + switch (nodeTag(expr)) { | ||
| 2713 | + case T_NamedArgExpr: | ||
| 2714 | + { | ||
| 2715 | + /* | ||
| 2716 | + * For NamedArgExpr we want to rewrite it from "<name> = | ||
| 2717 | + * <arg>" to "<name> => <arg>" | ||
| 2718 | + */ | ||
| 2719 | + const NamedArgExpr *na = (const NamedArgExpr *) expr; | ||
| 2720 | + | ||
| 2721 | + /* | ||
| 2722 | + * Append the part of stmt appearing before the | ||
| 2723 | + * NamedArgExpr that we haven't inserted already. | ||
| 2724 | + */ | ||
| 2725 | + appendBinaryStringInfo(&dest, &(stmt[prev]), | ||
| 2726 | + na->location - prev); | ||
| 2727 | + appendStringInfo(&dest, "\"%s\" => ", na->name); | ||
| 2728 | + prev = exprLocation((Node *) na->arg); | ||
| 2729 | + } | ||
| 2730 | + break; | ||
| 2731 | + default: | ||
| 2732 | + break; | ||
| 2733 | + } | ||
| 2734 | + } | ||
| 2735 | + | ||
| 2736 | + if (prev == firstArgLocation) /* no NamedArgExpr found */ | ||
| 2737 | + return NULL; | ||
| 2738 | + | ||
| 2739 | + appendStringInfoString(&dest, &(stmt[prev])); | ||
| 2740 | + return dest.data; | ||
| 2741 | +} | ||
| 2742 | + | ||
| 2743 | +static void prepare_select_plan_for_scalar_func(PLpgSQL_execstate *estate, | ||
| 2744 | + PLpgSQL_expr *expr, | ||
| 2745 | + int firstArgLocation, | ||
| 2746 | + const char *newParams) | ||
| 2747 | +{ | ||
| 2748 | + StringInfoData new_query; | ||
| 2749 | + char *savedExprQuery; | ||
| 2750 | + const char *startCommand = "EXEC"; | ||
| 2751 | + | ||
| 2752 | + /* expr->query should start with EXEC */ | ||
| 2753 | + Assert(strlen(startCommand) < strlen(expr->query)); | ||
| 2754 | + Assert(strstr(expr->query, startCommand) == expr->query); | ||
| 2755 | + | ||
| 2756 | + initStringInfo(&new_query); | ||
| 2757 | + if (firstArgLocation >= 0) { | ||
| 2758 | + if (newParams) { | ||
| 2759 | + appendStringInfo(&new_query, "SELECT %.*s (%s )", | ||
| 2760 | + firstArgLocation - (int) strlen(startCommand), | ||
| 2761 | + expr->query + strlen(startCommand), newParams); | ||
| 2762 | + } else { | ||
| 2763 | + appendStringInfo(&new_query, "SELECT %.*s (%s )", | ||
| 2764 | + firstArgLocation - (int) strlen(startCommand), | ||
| 2765 | + expr->query + strlen(startCommand), expr->query + firstArgLocation); | ||
| 2766 | + } | ||
| 2767 | + } else { | ||
| 2768 | + appendStringInfo(&new_query, "SELECT %s ()", expr->query + strlen(startCommand)); | ||
| 2769 | + } | ||
| 2770 | + | ||
| 2771 | + /* | ||
| 2772 | + * Now we got SELECT statement. Replace query string temporarily and | ||
| 2773 | + * prepare a SELECT plan | ||
| 2774 | + */ | ||
| 2775 | + savedExprQuery = expr->query; | ||
| 2776 | + expr->query = new_query.data; | ||
| 2777 | + | ||
| 2778 | + /* 'SELECT udf' will use simple_expr path. pass keepplan with true */ | ||
| 2779 | + exec_prepare_plan_interface(estate, expr, 0); | ||
| 2780 | + | ||
| 2781 | + expr->query = savedExprQuery; | ||
| 2782 | + | ||
| 2783 | + pfree(new_query.data); | ||
| 2784 | +} | ||
| @@ -4160,6 +4160,11 @@ List* extract_function_outarguments(Oid funcid, List* parameters, List* funcname | |||
| 4160 | return in_parameters; | 4160 | return in_parameters; |
| 4161 | } | 4161 | } |
| 4162 | 4162 | ||
| 4163 | +List* expand_function_arguments_interface(List* args, Oid result_type, HeapTuple func_tuple) | ||
| 4164 | +{ | ||
| 4165 | + return expand_function_arguments(args, result_type, func_tuple); | ||
| 4166 | +} | ||
| 4167 | + | ||
| 4163 | /* | 4168 | /* |
| 4164 | * expand_function_arguments: convert named-notation args to positional args | 4169 | * expand_function_arguments: convert named-notation args to positional args |
| 4165 | * and/or insert default args, as needed | 4170 | * and/or insert default args, as needed |
| @@ -56,6 +56,7 @@ | |||
| 56 | #include "plugin_parser/parse_cte.h" | 56 | #include "plugin_parser/parse_cte.h" |
| 57 | #include "plugin_parser/parse_hint.h" | 57 | #include "plugin_parser/parse_hint.h" |
| 58 | #include "plugin_parser/parse_merge.h" | 58 | #include "plugin_parser/parse_merge.h" |
| 59 | +#include "plugin_parser/parse_func.h" | ||
| 59 | #include "plugin_parser/parse_oper.h" | 60 | #include "plugin_parser/parse_oper.h" |
| 60 | #include "parser/parse_param.h" | 61 | #include "parser/parse_param.h" |
| 61 | #include "plugin_parser/parse_relation.h" | 62 | #include "plugin_parser/parse_relation.h" |
| @@ -142,6 +143,8 @@ static List* transformReturningList(ParseState* pstate, List* returningList); | |||
| 142 | static Query* transformDeclareCursorStmt(ParseState* pstate, DeclareCursorStmt* stmt); | 143 | static Query* transformDeclareCursorStmt(ParseState* pstate, DeclareCursorStmt* stmt); |
| 143 | static Query* transformExplainStmt(ParseState* pstate, ExplainStmt* stmt); | 144 | static Query* transformExplainStmt(ParseState* pstate, ExplainStmt* stmt); |
| 144 | static Query* transformCreateTableAsStmt(ParseState* pstate, CreateTableAsStmt* stmt); | 145 | static Query* transformCreateTableAsStmt(ParseState* pstate, CreateTableAsStmt* stmt); |
| 146 | +static Query* transformCallStmt(ParseState* pstate, DolphinCallStmt* stmt); | ||
| 147 | +static void CheckExecuteStmt(FuncExpr *fexpr, DolphinCallStmt *stmt, Datum proargmodes); | ||
| 145 | static void CheckDeleteRelation(Relation targetrel); | 148 | static void CheckDeleteRelation(Relation targetrel); |
| 146 | static void CheckUpdateRelation(Relation targetrel); | 149 | static void CheckUpdateRelation(Relation targetrel); |
| 147 | static void transformVariableSetValueStmt(ParseState* pstate, VariableSetStmt* stmt); | 150 | static void transformVariableSetValueStmt(ParseState* pstate, VariableSetStmt* stmt); |
| @@ -192,7 +195,6 @@ static Node* makeConstByType(Form_pg_attribute att_tup); | |||
| 192 | static Node* makeTimetypeConst(Oid targetType, int32 targetTypmod, Oid targetCollation, int16 targetLen, bool targetByval); | 195 | static Node* makeTimetypeConst(Oid targetType, int32 targetTypmod, Oid targetCollation, int16 targetLen, bool targetByval); |
| 193 | static Node* makeNotTimetypeConst(Oid targetType, int32 targetTypmod, Oid targetCollation, int16 targetLen, bool targetByval); | 196 | static Node* makeNotTimetypeConst(Oid targetType, int32 targetTypmod, Oid targetCollation, int16 targetLen, bool targetByval); |
| 194 | static List* makeValueLists(ParseState* pstate); | 197 | static List* makeValueLists(ParseState* pstate); |
| 195 | -static Query* transformCallStmt(ParseState *pstate, DolphinCallStmt *stmt); | ||
| 196 | static void replaceSubqueryCheck(Expr* expr, InsertStmt* stmt, ParseState* pstate); | 198 | static void replaceSubqueryCheck(Expr* expr, InsertStmt* stmt, ParseState* pstate); |
| 197 | #endif | 199 | #endif |
| 198 | 200 | ||
| @@ -748,11 +750,10 @@ Query* transformStmt(ParseState* pstate, Node* parseTree, bool isFirstNode, bool | |||
| 748 | result->commandType = CMD_UTILITY; | 750 | result->commandType = CMD_UTILITY; |
| 749 | result->utilityStmt = (Node*)parseTree; | 751 | result->utilityStmt = (Node*)parseTree; |
| 750 | break; | 752 | break; |
| 751 | - | ||
| 752 | - case T_DolphinCallStmt: | ||
| 753 | - result = transformCallStmt(pstate, (DolphinCallStmt *) parseTree); | ||
| 754 | - break; | ||
| 755 | #endif | 753 | #endif |
| 754 | + case T_DolphinCallStmt: | ||
| 755 | + result = transformCallStmt(pstate, (DolphinCallStmt*) parseTree); | ||
| 756 | + break; | ||
| 756 | default: | 757 | default: |
| 757 | 758 | ||
| 758 | /* | 759 | /* |
| @@ -5655,53 +5656,6 @@ static Query* transformCreateTableAsStmt(ParseState* pstate, CreateTableAsStmt* | |||
| 5655 | } | 5656 | } |
| 5656 | 5657 | ||
| 5657 | #ifdef DOLPHIN | 5658 | #ifdef DOLPHIN |
| 5658 | -/* | ||
| 5659 | - * transformCallStmt - | ||
| 5660 | - * transform a call xxx() Statement in B format; | ||
| 5661 | - *. | ||
| 5662 | - */ | ||
| 5663 | - | ||
| 5664 | -static Query* transformCallStmt(ParseState *pstate, DolphinCallStmt *stmt) | ||
| 5665 | -{ | ||
| 5666 | - List *targs; | ||
| 5667 | - ListCell *lc; | ||
| 5668 | - Node *node; | ||
| 5669 | - FuncExpr *fexpr; | ||
| 5670 | - HeapTuple proctup; | ||
| 5671 | - Query *result; | ||
| 5672 | - | ||
| 5673 | - targs = NIL; | ||
| 5674 | - /* transform all args to expr */ | ||
| 5675 | - foreach(lc, stmt->funccall->args) | ||
| 5676 | - { | ||
| 5677 | - targs = lappend(targs, transformExprRecurse(pstate, (Node *) lfirst(lc))); | ||
| 5678 | - } | ||
| 5679 | - | ||
| 5680 | - /* parse the function/procedure use function name */ | ||
| 5681 | - node = ParseFuncOrColumn(pstate, stmt->funccall->funcname, targs, pstate->p_last_srf, | ||
| 5682 | - stmt->funccall, stmt->funccall->location, true); | ||
| 5683 | - | ||
| 5684 | - assign_expr_collations(pstate, node); | ||
| 5685 | - | ||
| 5686 | - fexpr = castNode(FuncExpr, node); | ||
| 5687 | - | ||
| 5688 | - /* find procedure object in systemtable */ | ||
| 5689 | - proctup = SearchSysCache1(PROCOID, ObjectIdGetDatum(fexpr->funcid)); | ||
| 5690 | - if (!HeapTupleIsValid(proctup)) | ||
| 5691 | - ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("could not find procedure %u", fexpr->funcid))); | ||
| 5692 | - | ||
| 5693 | - stmt->funcexpr = fexpr; | ||
| 5694 | - | ||
| 5695 | - ReleaseSysCache(proctup); | ||
| 5696 | - | ||
| 5697 | - /* set as as a utility Query */ | ||
| 5698 | - result = makeNode(Query); | ||
| 5699 | - result->commandType = CMD_UTILITY; | ||
| 5700 | - result->utilityStmt = (Node *) stmt; | ||
| 5701 | - | ||
| 5702 | - return result; | ||
| 5703 | -} | ||
| 5704 | - | ||
| 5705 | /* | 5659 | /* |
| 5706 | * Replace into gram check | 5660 | * Replace into gram check |
| 5707 | * Replace into with inserted table in subselect should report error | 5661 | * Replace into with inserted table in subselect should report error |
| @@ -7431,3 +7385,118 @@ static Query* TryTransformInsertDirectly(ParseState* pstate, InsertStmt* stmt) | |||
| 7431 | 7385 | ||
| 7432 | return query; | 7386 | return query; |
| 7433 | } | 7387 | } |
| 7388 | + | ||
| 7389 | + | ||
| 7390 | +/* | ||
| 7391 | + * transform a CallStmt | ||
| 7392 | + */ | ||
| 7393 | +static Query *transformCallStmt(ParseState *pstate, DolphinCallStmt *stmt) | ||
| 7394 | +{ | ||
| 7395 | + ListCell *lc; | ||
| 7396 | + Node *node; | ||
| 7397 | + FuncExpr *fexpr; | ||
| 7398 | + HeapTuple proctup; | ||
| 7399 | + Datum proargmodes; | ||
| 7400 | + bool isNull; | ||
| 7401 | + List *targs = NIL; | ||
| 7402 | + Query *result; | ||
| 7403 | + | ||
| 7404 | + /* | ||
| 7405 | + * First, do standard parse analysis on the procedure call and its | ||
| 7406 | + * arguments, allowing us to identify the called procedure. | ||
| 7407 | + */ | ||
| 7408 | + foreach(lc, stmt->funccall->args) { | ||
| 7409 | + targs = lappend(targs, transformExprRecurse(pstate, (Node *) lfirst(lc))); | ||
| 7410 | + } | ||
| 7411 | + | ||
| 7412 | + node = ParseFuncOrColumn(pstate, | ||
| 7413 | + stmt->funccall->funcname, | ||
| 7414 | + targs, | ||
| 7415 | + pstate->p_last_srf, | ||
| 7416 | + stmt->funccall, | ||
| 7417 | + stmt->funccall->location, | ||
| 7418 | + true); | ||
| 7419 | + | ||
| 7420 | + assign_expr_collations(pstate, node); | ||
| 7421 | + | ||
| 7422 | + fexpr = castNode(FuncExpr, node); | ||
| 7423 | + | ||
| 7424 | + proctup = SearchSysCache1(PROCOID, ObjectIdGetDatum(fexpr->funcid)); | ||
| 7425 | + if (!HeapTupleIsValid(proctup)) | ||
| 7426 | + elog(ERROR, "cache lookup failed for function %u", fexpr->funcid); | ||
| 7427 | + | ||
| 7428 | + if (stmt->outargs == NULL) { | ||
| 7429 | + /* | ||
| 7430 | + * Expand the argument list to deal with named-argument notation and | ||
| 7431 | + * default arguments. For ordinary FuncExprs this'd be done during | ||
| 7432 | + * planning, but a CallStmt doesn't go through planning, and there seems | ||
| 7433 | + * no good reason not to do it here. | ||
| 7434 | + */ | ||
| 7435 | + fexpr->args = expand_function_arguments_interface(fexpr->args, | ||
| 7436 | + fexpr->funcresulttype, | ||
| 7437 | + proctup); | ||
| 7438 | + | ||
| 7439 | + /* Fetch proargmodes; if it's null, there are no output args */ | ||
| 7440 | + proargmodes = SysCacheGetAttr(PROCOID, proctup, | ||
| 7441 | + Anum_pg_proc_proargmodes, | ||
| 7442 | + &isNull); | ||
| 7443 | + if (!isNull) { | ||
| 7444 | + CheckExecuteStmt(fexpr, stmt, proargmodes); | ||
| 7445 | + } | ||
| 7446 | + } | ||
| 7447 | + stmt->funcexpr = fexpr; | ||
| 7448 | + | ||
| 7449 | + ReleaseSysCache(proctup); | ||
| 7450 | + | ||
| 7451 | + /* represent the command as a utility Query */ | ||
| 7452 | + result = makeNode(Query); | ||
| 7453 | + result->commandType = CMD_UTILITY; | ||
| 7454 | + result->utilityStmt = (Node *) stmt; | ||
| 7455 | + | ||
| 7456 | + return result; | ||
| 7457 | +} | ||
| 7458 | + | ||
| 7459 | +static void CheckExecuteStmt(FuncExpr *fexpr, DolphinCallStmt *stmt, Datum proargmodes) | ||
| 7460 | +{ | ||
| 7461 | + ListCell *lc; | ||
| 7462 | + ArrayType *arr; | ||
| 7463 | + List *outargs = NIL; | ||
| 7464 | + List *inargs = NIL; | ||
| 7465 | + char *argmodes; | ||
| 7466 | + int numargs; | ||
| 7467 | + int i = 0; | ||
| 7468 | + | ||
| 7469 | + arr = DatumGetArrayTypeP(proargmodes); /* ensure not toasted */ | ||
| 7470 | + numargs = list_length(fexpr->args); | ||
| 7471 | + if (ARR_NDIM(arr) != 1 || | ||
| 7472 | + ARR_HASNULL(arr) || | ||
| 7473 | + ARR_ELEMTYPE(arr) != CHAROID) | ||
| 7474 | + elog(ERROR, "proargmodes is not a 1-D char array of length %d or it contains nulls", numargs); | ||
| 7475 | + argmodes = (char *) ARR_DATA_PTR(arr); | ||
| 7476 | + | ||
| 7477 | + if (numargs == ARR_DIMS(arr)[0]) { | ||
| 7478 | + foreach(lc, fexpr->args) { | ||
| 7479 | + Node *n = (Node *)lfirst(lc); | ||
| 7480 | + switch (argmodes[i]) { | ||
| 7481 | + case PROARGMODE_IN: | ||
| 7482 | + case PROARGMODE_VARIADIC: | ||
| 7483 | + inargs = lappend(inargs, n); | ||
| 7484 | + break; | ||
| 7485 | + case PROARGMODE_OUT: | ||
| 7486 | + outargs = lappend(outargs, n); | ||
| 7487 | + break; | ||
| 7488 | + case PROARGMODE_INOUT: | ||
| 7489 | + inargs = lappend(inargs, n); | ||
| 7490 | + outargs = lappend(outargs, copyObject(n)); | ||
| 7491 | + break; | ||
| 7492 | + default: | ||
| 7493 | + /* note we don't support PROARGMODE_TABLE */ | ||
| 7494 | + elog(ERROR, "invalid argmode %c for procedure", argmodes[i]); | ||
| 7495 | + break; | ||
| 7496 | + } | ||
| 7497 | + i++; | ||
| 7498 | + } | ||
| 7499 | + fexpr->args = inargs; | ||
| 7500 | + } | ||
| 7501 | + stmt->outargs = outargs; | ||
| 7502 | +} | ||
| @@ -32936,7 +32936,7 @@ table_ref_for_no_table_function: single_table | |||
| 32936 | { | 32936 | { |
| 32937 | $$ = $1; | 32937 | $$ = $1; |
| 32938 | } | 32938 | } |
| 32939 | - | LATERAL_EXPR func_table alias_clause | 32939 | + | LATERAL_EXPR func_table dolphin_alias_clause |
| 32940 | { | 32940 | { |
| 32941 | RangeFunction *n = makeNode(RangeFunction); | 32941 | RangeFunction *n = makeNode(RangeFunction); |
| 32942 | n->funccallnode = $2; | 32942 | n->funccallnode = $2; |
| @@ -32952,7 +32952,7 @@ table_ref_for_no_table_function: single_table | |||
| 32952 | n->coldeflist = NIL; | 32952 | n->coldeflist = NIL; |
| 32953 | $$ = (Node *) n; | 32953 | $$ = (Node *) n; |
| 32954 | } | 32954 | } |
| 32955 | - | func_table alias_clause | 32955 | + | func_table dolphin_alias_clause |
| 32956 | { | 32956 | { |
| 32957 | RangeFunction *n = makeNode(RangeFunction); | 32957 | RangeFunction *n = makeNode(RangeFunction); |
| 32958 | n->funccallnode = $1; | 32958 | n->funccallnode = $1; |
| @@ -32967,22 +32967,22 @@ table_ref_for_no_table_function: single_table | |||
| 32967 | n->coldeflist = $4; | 32967 | n->coldeflist = $4; |
| 32968 | $$ = (Node *) n; | 32968 | $$ = (Node *) n; |
| 32969 | } | 32969 | } |
| 32970 | - | func_table AS ColId '(' TableFuncElementList ')' | 32970 | + | func_table AS DolphinColId '(' TableFuncElementList ')' |
| 32971 | { | 32971 | { |
| 32972 | RangeFunction *n = makeNode(RangeFunction); | 32972 | RangeFunction *n = makeNode(RangeFunction); |
| 32973 | Alias *a = makeNode(Alias); | 32973 | Alias *a = makeNode(Alias); |
| 32974 | n->funccallnode = $1; | 32974 | n->funccallnode = $1; |
| 32975 | - a->aliasname = $3; | 32975 | + a->aliasname = GetDolphinObjName($3->str, $3->is_quoted); |
| 32976 | n->alias = a; | 32976 | n->alias = a; |
| 32977 | n->coldeflist = $5; | 32977 | n->coldeflist = $5; |
| 32978 | $$ = (Node *) n; | 32978 | $$ = (Node *) n; |
| 32979 | } | 32979 | } |
| 32980 | - | func_table ColId '(' TableFuncElementList ')' | 32980 | + | func_table DolphinColId '(' TableFuncElementList ')' |
| 32981 | { | 32981 | { |
| 32982 | RangeFunction *n = makeNode(RangeFunction); | 32982 | RangeFunction *n = makeNode(RangeFunction); |
| 32983 | Alias *a = makeNode(Alias); | 32983 | Alias *a = makeNode(Alias); |
| 32984 | n->funccallnode = $1; | 32984 | n->funccallnode = $1; |
| 32985 | - a->aliasname = $2; | 32985 | + a->aliasname = GetDolphinObjName($2->str, $2->is_quoted); |
| 32986 | n->alias = a; | 32986 | n->alias = a; |
| 32987 | n->coldeflist = $4; | 32987 | n->coldeflist = $4; |
| 32988 | $$ = (Node *) n; | 32988 | $$ = (Node *) n; |
| @@ -45613,7 +45613,8 @@ static void with_rollup_check_elems_count(Node* expr) | |||
| 45613 | 45613 | ||
| 45614 | static inline char* GetDolphinObjName(char* string, bool is_quoted) | 45614 | static inline char* GetDolphinObjName(char* string, bool is_quoted) |
| 45615 | { | 45615 | { |
| 45616 | - return (GetSessionContext()->lower_case_table_names == 0) ? string : downcase_str(string, is_quoted); | 45616 | + return (GetSessionContext()->lower_case_table_names == 0 && !u_sess->attr.attr_common.IsInplaceUpgrade) ? |
| 45617 | + string : downcase_str(string, is_quoted); | ||
| 45617 | } | 45618 | } |
| 45618 | 45619 | ||
| 45619 | static inline char* GetDolphinSchemaName(char* string, bool is_quoted) | 45620 | static inline char* GetDolphinSchemaName(char* string, bool is_quoted) |
| @@ -5171,11 +5171,9 @@ void standard_ProcessUtility(processutility_context* processutility_cxt, | |||
| 5171 | GetDiagStmt *n = (GetDiagStmt *)parse_tree; | 5171 | GetDiagStmt *n = (GetDiagStmt *)parse_tree; |
| 5172 | getDiagnosticsInfo(n->condInfo, n->hasCondNum, n->condNum); | 5172 | getDiagnosticsInfo(n->condInfo, n->hasCondNum, n->condNum); |
| 5173 | } break; | 5173 | } break; |
| 5174 | -#ifdef DOLPHIN | ||
| 5175 | case T_DolphinCallStmt: { | 5174 | case T_DolphinCallStmt: { |
| 5176 | - ExecuteCallStmt(castNode(DolphinCallStmt, parse_tree), params, false); | 5175 | + ExecuteCallStmt((DolphinCallStmt *)parse_tree, params, false, dest); |
| 5177 | } break; | 5176 | } break; |
| 5178 | -#endif | ||
| 5179 | default: { | 5177 | default: { |
| 5180 | ProcessUtilitySlow(parse_tree, query_string, params, dest, | 5178 | ProcessUtilitySlow(parse_tree, query_string, params, dest, |
| 5181 | #ifdef PGXC | 5179 | #ifdef PGXC |
| @@ -31,6 +31,7 @@ | |||
| 31 | #include "utils/json.h" | 31 | #include "utils/json.h" |
| 32 | #include "utils/typcache.h" | 32 | #include "utils/typcache.h" |
| 33 | #include "utils/syscache.h" | 33 | #include "utils/syscache.h" |
| 34 | +#include "port/simd.h" | ||
| 34 | 35 | ||
| 35 | #ifdef DOLPHIN | 36 | #ifdef DOLPHIN |
| 36 | #include "plugin_postgres.h" | 37 | #include "plugin_postgres.h" |
| @@ -2235,6 +2236,145 @@ Datum json_typeof(PG_FUNCTION_ARGS) | |||
| 2235 | PG_RETURN_TEXT_P(cstring_to_text(type)); | 2236 | PG_RETURN_TEXT_P(cstring_to_text(type)); |
| 2236 | } | 2237 | } |
| 2237 | 2238 | ||
| 2239 | +/* | ||
| 2240 | + * escape_json_char | ||
| 2241 | + * Inline helper function for escape_json* functions | ||
| 2242 | + */ | ||
| 2243 | +static void escape_json_char(StringInfo buf, char c) | ||
| 2244 | +{ | ||
| 2245 | + switch (c) { | ||
| 2246 | + case '\b': | ||
| 2247 | + appendStringInfoString(buf, "\\b"); | ||
| 2248 | + break; | ||
| 2249 | + case '\f': | ||
| 2250 | + appendStringInfoString(buf, "\\f"); | ||
| 2251 | + break; | ||
| 2252 | + case '\n': | ||
| 2253 | + appendStringInfoString(buf, "\\n"); | ||
| 2254 | + break; | ||
| 2255 | + case '\r': | ||
| 2256 | + appendStringInfoString(buf, "\\r"); | ||
| 2257 | + break; | ||
| 2258 | + case '\t': | ||
| 2259 | + appendStringInfoString(buf, "\\t"); | ||
| 2260 | + break; | ||
| 2261 | + case '"': | ||
| 2262 | + appendStringInfoString(buf, "\\\""); | ||
| 2263 | + break; | ||
| 2264 | + case '\\': | ||
| 2265 | + appendStringInfoString(buf, "\\\\"); | ||
| 2266 | + break; | ||
| 2267 | + default: | ||
| 2268 | + if ((unsigned char)c < ' ') { | ||
| 2269 | + appendStringInfo(buf, "\\u%04x", (int) c); | ||
| 2270 | + } else { | ||
| 2271 | + appendStringInfoCharMacro(buf, c); | ||
| 2272 | + } | ||
| 2273 | + break; | ||
| 2274 | + } | ||
| 2275 | +} | ||
| 2276 | + | ||
| 2277 | +/* | ||
| 2278 | + * escape_json_with_len | ||
| 2279 | + * Produce a JSON string literal, properly escaping the possibly not | ||
| 2280 | + * NUL-terminated characters in 'str'. 'len' defines the number of bytes | ||
| 2281 | + * from 'str' to process. | ||
| 2282 | + */ | ||
| 2283 | +void escape_json_with_len(StringInfo buf, const char *str, int len) | ||
| 2284 | +{ | ||
| 2285 | + int vlen; | ||
| 2286 | + | ||
| 2287 | + Assert(len >= 0); | ||
| 2288 | + | ||
| 2289 | + /* | ||
| 2290 | + * Since we know the minimum length we'll need to append, let's just | ||
| 2291 | + * enlarge the buffer now rather than incrementally making more space when | ||
| 2292 | + * we run out. Add two extra bytes for the enclosing quotes. | ||
| 2293 | + */ | ||
| 2294 | + int paddingLen = 2; | ||
| 2295 | + enlargeStringInfo(buf, len + paddingLen); | ||
| 2296 | + | ||
| 2297 | + /* | ||
| 2298 | + * Figure out how many bytes to process using SIMD. Round 'len' down to | ||
| 2299 | + * the previous multiple of sizeof(Vector8), assuming that's a power-of-2. | ||
| 2300 | + */ | ||
| 2301 | + vlen = len & (int) (~(sizeof(Vector8) - 1)); | ||
| 2302 | + | ||
| 2303 | + appendStringInfoCharMacro(buf, '"'); | ||
| 2304 | + | ||
| 2305 | + for (int i = 0, copypos = 0;;) { | ||
| 2306 | + /* | ||
| 2307 | + * To speed this up, try searching sizeof(Vector8) bytes at once for | ||
| 2308 | + * special characters that we need to escape. When we find one, we | ||
| 2309 | + * fall out of the Vector8 loop and copy the portion we've vector | ||
| 2310 | + * searched and then we process sizeof(Vector8) bytes one byte at a | ||
| 2311 | + * time. Once done, come back and try doing vector searching again. | ||
| 2312 | + * We'll also process any remaining bytes at the tail end of the | ||
| 2313 | + * string byte-by-byte. This optimization assumes that most chunks of | ||
| 2314 | + * sizeof(Vector8) bytes won't contain any special characters. | ||
| 2315 | + */ | ||
| 2316 | + for (; i < vlen; i += sizeof(Vector8)) { | ||
| 2317 | + Vector8 chunk; | ||
| 2318 | + | ||
| 2319 | + vector8_load(&chunk, (const uint8 *) &str[i]); | ||
| 2320 | + | ||
| 2321 | + /* | ||
| 2322 | + * Break on anything less than ' ' or if we find a '"' or '\\'. | ||
| 2323 | + * Those need special handling. That's done in the per-byte loop. | ||
| 2324 | + */ | ||
| 2325 | + if (vector8_has_le(chunk, (unsigned char) 0x1F) || | ||
| 2326 | + vector8_has(chunk, (unsigned char) '"') || | ||
| 2327 | + vector8_has(chunk, (unsigned char) '\\')) { | ||
| 2328 | + break; | ||
| 2329 | + } | ||
| 2330 | + | ||
| 2331 | +#ifdef ESCAPE_JSON_FLUSH_AFTER | ||
| 2332 | + | ||
| 2333 | + /* | ||
| 2334 | + * Flush what's been checked so far out to the destination buffer | ||
| 2335 | + * every so often to avoid having to re-read cachelines when | ||
| 2336 | + * escaping large strings. | ||
| 2337 | + */ | ||
| 2338 | + if (i - copypos >= ESCAPE_JSON_FLUSH_AFTER) { | ||
| 2339 | + appendBinaryStringInfo(buf, &str[copypos], i - copypos); | ||
| 2340 | + copypos = i; | ||
| 2341 | + } | ||
| 2342 | +#endif | ||
| 2343 | + } | ||
| 2344 | + | ||
| 2345 | + /* | ||
| 2346 | + * Write to the destination up to the point that we've vector searched | ||
| 2347 | + * so far. Do this only when switching into per-byte mode rather than | ||
| 2348 | + * once every sizeof(Vector8) bytes. | ||
| 2349 | + */ | ||
| 2350 | + if (copypos < i) { | ||
| 2351 | + appendBinaryStringInfo(buf, &str[copypos], i - copypos); | ||
| 2352 | + copypos = i; | ||
| 2353 | + } | ||
| 2354 | + | ||
| 2355 | + /* | ||
| 2356 | + * Per-byte loop for Vector8s containing special chars and for | ||
| 2357 | + * processing the tail of the string. | ||
| 2358 | + */ | ||
| 2359 | + for (int b = 0; b < sizeof(Vector8); b++) { | ||
| 2360 | + /* check if we've finished */ | ||
| 2361 | + if (i == len) { | ||
| 2362 | + goto done; | ||
| 2363 | + } | ||
| 2364 | + | ||
| 2365 | + Assert(i < len); | ||
| 2366 | + | ||
| 2367 | + escape_json_char(buf, str[i++]); | ||
| 2368 | + } | ||
| 2369 | + | ||
| 2370 | + copypos = i; | ||
| 2371 | + /* We're not done yet. Try the vector search again. */ | ||
| 2372 | + } | ||
| 2373 | + | ||
| 2374 | +done: | ||
| 2375 | + appendStringInfoCharMacro(buf, '"'); | ||
| 2376 | +} | ||
| 2377 | + | ||
| 2238 | #ifdef DOLPHIN | 2378 | #ifdef DOLPHIN |
| 2239 | Datum json_array(PG_FUNCTION_ARGS) | 2379 | Datum json_array(PG_FUNCTION_ARGS) |
| 2240 | { | 2380 | { |
| @@ -474,47 +474,10 @@ struct OvalsState { | |||
| 474 | char* result_start; | 474 | char* result_start; |
| 475 | }; | 475 | }; |
| 476 | 476 | ||
| 477 | -struct JsonPathContext { | ||
| 478 | - text* topJson; | ||
| 479 | - int relax; | ||
| 480 | -}; | ||
| 481 | - | ||
| 482 | -struct JsonExistsPathContext { | ||
| 483 | - JsonPathContext cxt; | ||
| 484 | - bool result; | ||
| 485 | -}; | ||
| 486 | - | ||
| 487 | -struct JsonTextContainsContext { | ||
| 488 | - JsonPathContext cxt; | ||
| 489 | - char* target; | ||
| 490 | - bool result; | ||
| 491 | -}; | ||
| 492 | - | ||
| 493 | -struct JsonStringArray { | ||
| 494 | - char** data; | ||
| 495 | - int len; | ||
| 496 | - int maxlen; | ||
| 497 | -}; | ||
| 498 | - | ||
| 499 | /* Turn a jsonb object into a record */ | 477 | /* Turn a jsonb object into a record */ |
| 500 | static void make_row_from_rec_and_jsonb(Jsonb *element, PopulateRecordsetState *state); | 478 | static void make_row_from_rec_and_jsonb(Jsonb *element, PopulateRecordsetState *state); |
| 501 | - | ||
| 502 | -/* functions supporting json_exists and json_textcontains */ | ||
| 503 | -static bool IsJsonText(text* t); | ||
| 504 | -static void JsonPathWalker(JsonPathItem* path, text* json, void (*pwalker)(text*, void*), void* context); | ||
| 505 | -static void JPWalkArrayStep(JsonPathItem* path, text* json, void (*pwalker)(text*, void*), void* context); | ||
| 506 | -static void JPWalkObjectStep(JsonPathItem* path, text* json, void (*pwalker)(text*, void*), void* context); | ||
| 507 | static OvalsState* json_object_values_internal(text* json); | 479 | static OvalsState* json_object_values_internal(text* json); |
| 508 | 480 | ||
| 509 | -/* functions supporting json_exists */ | ||
| 510 | -static void JsonPathExistsPathWalker(text* json, JsonExistsPathContext* context); | ||
| 511 | - | ||
| 512 | -/* functions supporting json_textcontains */ | ||
| 513 | -static List* GetObjectValues(text* json); | ||
| 514 | -static void SplitString(char* str, char delim, int strlen, JsonStringArray* results); | ||
| 515 | -static void CollectValsFromJson(text* json, JsonStringArray* vals); | ||
| 516 | -static void JsonTextContainsWalker(text* json, JsonTextContainsContext* context); | ||
| 517 | - | ||
| 518 | #ifdef DOLPHIN | 481 | #ifdef DOLPHIN |
| 519 | PG_FUNCTION_INFO_V1_PUBLIC(json_contains); | 482 | PG_FUNCTION_INFO_V1_PUBLIC(json_contains); |
| 520 | extern "C" DLL_PUBLIC Datum json_contains(PG_FUNCTION_ARGS); | 483 | extern "C" DLL_PUBLIC Datum json_contains(PG_FUNCTION_ARGS); |
| @@ -566,3 +566,6 @@ drop table table_json_a; | |||
| 566 | drop table table_json_b; | 566 | drop table table_json_b; |
| 567 | 567 | ||
| 568 | drop table t1; | 568 | drop table t1; |
| 569 | + | ||
| 570 | +set dolphin.lower_case_table_names = 0; | ||
| 571 | +select S.type from gs_get_hba_conf() S limit 1; | ||